文档视界 最新最全的文档下载
当前位置:文档视界 › 汇编语言课后习题解答

汇编语言课后习题解答

汇编语言课后习题解答
汇编语言课后习题解答

第1章基础知识

检测点(第9页)

(1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为13位。

(2)1KB的存储器有1024个存储单元,存储单元的编号从0到1023。

(3)1KB的存储器可以存储8192(2^13)个bit,1024个Byte。

~

(4)1GB是24(2^30)个Byte、1MB是1048576(2^20)个Byte、1KB是1024(2^10)个Byte。

(5)8080、8088、80296、80386的地址总线宽度分别为16根、20根、24根、32根,则它们的寻址能力分别为: 64(KB)、1(MB)、16(MB)、4(GB)。

(6)8080、8088、8086、80286、80386的数据总线宽度分别为8根、8根、16根、16根、32根。则它们一次可以传送的数据为: 1(B)、1(B)、2(B)、2(B)、4(B)。

(7)从内存中读取1024字节的数据,8086至少要读512次,80386至少要读256次。

(8)在存储器中,数据和程序以二进制形式存放。

解题过程:

}

(1)1KB=1024B,8KB=1024B*8=2^N,N=13。

(2)存储器的容量是以字节为最小单位来计算的,1KB=1024B。

(3)8Bit=1Byte,1024Byte=1KB(1KB=1024B=1024B*8Bit)。

(4)1GB=24B(即2^30)1MB=1048576B(即2^20)1KB=1024B(即2^10)。

(5)一个CPU有N根地址线,则可以说这个CPU的地址总线的宽度为N。这样的CPU最多可以寻找2的N次方个内存单元。(一个内存单元=1Byte)。

(6)8根数据总线一次可以传送8位二进制数据(即一个字节)。

(7)8086的数据总线宽度为16根(即一次传送的数据为2B)1024B/2B=512,同理1024B/4B=256。

(8)在存储器中指令和数据没有任何区别,都是二进制信息。

<

第2章寄存器

检测点(第19页)

(1)写出每条汇编指令执行后相关寄存器中的值。第一空:F4A3H

第二空:31A3H

第三空:3123H

第四空:6246H

第五空:826CH

第六空:6246H

第七空:826CH

第八空:04D8H

第九空:0482H

第十空:6C82H

第十一空:D882H

第十二空:D888H

第十三空:D810H

第十四空:6246H

(2)只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方。

解答如下:

mov ax,2

add ax,ax

add ax,ax

add ax,ax

检测点(第25页)

(1)00010H,1000FH

(2)1001H,2000H

?

第2题说明:

因为段的起始地址要为16的倍数。所以当段地址小于1001H或大于2000H时CPU都无法寻到。

(1)解题过程:

物理地址=SA*16+EA

EA的变化范围为0h~ffffh

物理地址范围为(SA*16+0h)~(SA*16+ffffh)

现在SA=0001h,那么寻址范围为

(0001h*16+0h)~(0001h*16+ffffh)

=0010h~1000fh

(2)解题过程:

物理地址=SA*16+EA

20000h=SA*16+EA

SA=(20000h-EA)/16=2000h-EA/16

EA取最大值时,SA=2000h-ffffh/16=1001h,SA为最小值

EA取最小值时,SA=2000h-0h/16=2000h,SA为最大值

这里的ffffH/16=fffh是通过WIN自带计算器算的

按位移来算确实应该为,这里小数点后的f应该是省略了

单就除法来说,应有商和余数,但此题要求的是地址最大和最小,所以余数忽略了

.

如果根据位移的算法(段地址*16=16进制左移一位),小数点后应该是不能省略的我们可以反过来再思考下,如果SA为1000h的话,小数点后省略

SA=1000h,EA取最大ffffh,物理地址为1ffffh,将无法寻到20000H单元

这道题不应看成是单纯的计算题

[

检测点(第35页)

答:CPU修改了4次IP的值。

情况如下:

第1次:执行完mov ax,bx后

第2次:执行完sub ax,ax后;该步执行后,寄存器ax清零

第3次:读入jmp ax后

第4次:执行完jmp ax后;连续两步ip均为0

最后IP的值为0

;最后IP的值为0000H,因为最后ax中的值为0000H,所以IP中的值也为0000H

第三章寄存器(内存访问)

检测点(第55页)

(1)(题目:略)

第一空:2662H

第二空:E626H

第三空:E626H

第四空:2662H

第五空:D6E6H

第六空:FD48H

第七空:2C14H

第八空:0000H

第九空:00E6H

第十空:0000H

第十一空:0026H

第十二空:000CH

提示:此题可在DEBUG中利用E命令在本机上按照题目中所给出的内存单元及其数据进行相应地修改,然后再用A命令进行写入(题目中所给出的)相应的汇编指令,最后再进行T命令进行逐步执行,以查看相应结果。

(2)指令序列如下:

(3)mov ax,6622h

(4)jmp 0ff0:0100

(5)mov ax,2000h

(6)mov ds,ax

(7)mov ax,[0008]

(8)mov ax,[0002]

2.写出CPU执行每条指令后,CS、IP和相关寄存器中的数值。

指令序列

,

寄存器→

CS IP DS AX BX

初始值→2000H0000、

1000H

00

mov ax,6622h2000H00031000H6622H0000 jmp 0ff0:0100\

00001000H6622H0000

1000H

mov ax,2000h1000H00031000H2000H,

0000 mov ds,ax1000H00052000H2000H0000 mov ax,[0008]1000H0008/

C389H0000

2000H

mov ax,[0002]1000H000B2000H EA66H0000

\

3.再次体会:数据和程序有区别吗如何确定内存中的信息哪些是数据,哪些是程序?

检测点(第70页)

(1)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH 中。

mov ax,1000H

mov ds,ax

mov ax,2000H

mov ss,ax

mov sp,10h

(2)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH 中。

mov ax,2000H

mov ds, ax

mov ax,1000H

mov ss, ax

mov sp,0

"

检测点(第129页)

*

(1)下面的程序实现依次用内存0:0~0:15单元中的内容改写程序中的数据,完成程序:

assume cs:codesg

codesg segment

dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h

start: mov ax,0

mov ds, ax

mov bx,0

mov cx,8

s: mov ax,[bx]

mov cs:[bx],ax

add bx,2

loop s

mov ax,4c00h

int 21h

codesg ends

end start

.

(2)下面的程序实现依次用内存0:0~0:15单元中的内容改写程序中的数据,数据的传送用栈来进行。栈空间设置在程序内。完成程序:

assume cs:codesg

codesg segment

dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h

dw 0,0,0,0,0,0,0,0,0,0

;10个字单元用作栈空间,所以栈空间的大小为10*2=20,化成16进制即为14 start: mov ax, codesg;或mov ax, cs

mov ss ,ax

mov sp, 24h;或mov sp, 36;10h+14h=24h

mov ax,0

mov ds, ax

mov bx,0

mov cx,8

s: push [bx]

pop cs:[bx];或pop ss:[bx] ;关键在于cs与ss此时地址相同

add bx,2

loop s

mov ax,4c00h

int 21h

codesg ends

end start

检测点(第183页)

(1)程序如下:

assume cs:code

data segment

dw 2 dup (0)

data ends

:

code segment

start: mov ax, data

mov ds, ax

mov bx,0

jmp word ptr [bx+1]

code ends

end start

(

若要使jmp指令执行后,CS:IP指向程序的第一条指令,在data段中应该定义哪些数据

答案①db 3 dup (0)

答案②dw 2 dup (0)

答案③dd 0

jmp word ptr [bx+1]为段内转移,要CS:IP指向程序的第一条指令,应设置ds:[bx+1]的字单元(2个字节)存放数据应为0,则(ip)=ds:[bx+1]=0

简单来说就是,只要ds:[bx+1]起始地址的两个字节为0就可以了

~

(2)程序如下:

assume cs:code

data segment

dd h

data ends

code segment

start: mov ax,data

mov ds,ax

mov bx,0

mov [bx], bx;或mov [bx], word ptr 0;或mov [bx], offset start

mov [bx+2], cs;或mov [bx+2], cs ;或mov [bx+2], seg code

jmp dword ptr ds:[0]

.

code ends

end start

补全程序,使用jmp指令执行后,CS:IP指向程序的第一条指令。

第一格可填①mov [bx],bx ②mov [bx],word ptr 0 ③mov [bx],offset start等。

第二格可填①mov [bx+2],cs ②mov [bx+2],cs ③mov [bx+2],seg code等。

解析:

jmp dword ptr ds:[0]为段间转移,(cs)=(内存单元地址+2),(ip)=(内存单元地址),要CS:IP指向程序的第一条指令,第一条程序地址cs:0,应设置CS:IP指向cs:0

程序中的mov [bx],bx这条指令,是将ip设置为0

mov [bx+2],cs,将cs这个段地址放入内存单元

执行后,cs应该不变,只调整ip为0,(ip)=ds:[0]=0

(3)用Debug查看内存,结果如下:

.

2000:1000 BE 00 06 00 00 00 ......

则此时,CPU执行指令:

mov ax,2000h

mov es,ax

jmp dword ptr es:[1000h]

后,(cs)= 0006H,(ip)= 00BEH

解析:

jmp dword ptr为段间转移,高位存放段地址,低位存放偏移地址

(cs)=(内存单元地址+2),(ip)=(内存单元地址)

根据书P16,对于寄存器AX,AH为高位(前1字节为高位),AL为低位(后1字节为低位)

推算出(内存单元地址)=00BEH,(内存单元地址+2)=0006H

根据书P182,高位存放段地址(后2个字节为高位),低位存放偏移地址(前2个字节为低位) (cs)=(内存单元地址+2),(ip)=(内存单元地址)

推算出(cs)=0006H,(ip)=00BEH.

检测点(第184页)

%

补全编程,利用jcxz指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。

assume cs:code

code segment

·

start: mov ax,2000h

mov ds, ax

mov bx,0

s: mov ch,0

mov cl,[bx]

jcxz ok;当cx=0时,CS:IP指向OK

inc bx

jmp short s

ok: mov dx, bx

.

mov ax ,4c00h

int 21h

code ends

end start

检测点(第185页)

补全编程,利用loop指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。

assume cs:code

code segment

start: mov ax,2000h

mov ds, ax

mov bx,0

s:mov cl,[bx]

/

mov ch,0

inc cx ;只要保证cx>0,才能执行loop循环,切记!

inc bx

loop s

ok: dec bx

mov dx, bx

mov ax,4c00h

int 21h

code ends

^

end start

检测点(第191页)

补全程序,实现从内存1000:0000处开始执行指令。

assume cs:code

stack segment

db 16 dup (0)

stack ends

code segment

start: mov ax, stack

mov ss, ax

mov sp,16

mov ax, 1000h

push ax

mov ax, 0

push ax

retf

code ends

end start

/

执行reft指令时,相当于进行:

pop ip

pop cs

根据栈先进后出原则,应先将段地址cs入栈,再将偏移地址ip入栈。

检测点(第192页)

下面的程序执行后,ax中的数值为多少

?

内存地址机器码汇编指令执行后情况

1000:0 b8 00 00 mov ax,0 ax=0 ip指向1000:3

1000:3 e8 01 00 call s pop ip ip指向1000:7

1000:6 40 inc ax

1000:7 58 s:pop ax ax=6

用debug进行跟踪确认,“call标号”是将该指令后的第一个字节偏移地址入栈,再转到标号处执行指令。

[

检测点(第192页)

下面的程序执行后,ax中的数值为多少

内存地址机器码汇编指令执行后情况

1000:0 b8 00 00 mov ax,0 ax=0, ip指向1000:3

1000:3 9a 09 00 00 10 call far ptr s pop cs,pop ip,ip指向1000:9

1000:840 inc ax

1000:9 58 s: pop ax ax=8h

add ax,ax ax=10h

pop bx bx=1000h

add ax,bx ax=1010h

检测点(第194页)

下面的程序执行后,ax中的数值为多少

内存地址机器码汇编指令执行后情况

1000:0 b8 06 00 mov ax,6 ax=6, ip指向1000:3

1000:3 ff d0 call ax pop ip, ip指向1000:6

1000:5 40 inc ax

1000:6 58 mov bp ,sp bp=sp=fffeh ;栈顶的地址减去2,存放着05h

add ax,[bp] ax=[6+ds:(fffeh)]=6+5=0bh

用debug进行跟踪确认,“call ax(16位reg)”是先将该指令后的第一个字节偏移地址ip入栈,再转到偏移地址为ax(16位reg)处执行指令。

编译无法通过,只能理论分析.

$

检测点(第195页)

(1)下面的程序执行后,ax中的数值为多少assume cs:code

stack segment

dw 8 dup (0)

stack ends

$

code segment

start: mov ax, stack

mov ss, ax

mov sp,16

mov ds, ax

mov ax,0

call word ptr ds:[0eh]

inc ax

inc ax

inc ax

&

mov ax,4c00h

int 21h

code ends

end start

~

当程序执行call word ptr ds:[0EH]语句时,相当于进行:

1: PUSH IP(此时IP的值为CALL语句下一条语句的偏移地址,也就是INC AX的偏移地址)

2: JMP WORD PTR SS(因为DS等于SS):[0EH],此时程序跳转到CS:SS:[OEH]处执行,因为SS:[0EH]的值为0,所以跳转到CS:0处开始执行,也就是程序的第一条语句MOV AX, STACK,当程序再一次执行到call word ptr ds:[0EH]时,又进行上面的两步,但是此时SS:[OEH]的值已经不是0了,而是上一次执行PUSH IP时,压入的IP的值,而这个IP正是CALL语句下一条语句的偏移地址,也就是INC AX的偏移地址.所以程序跳转到语句INC AX处执行,所以AX的值为3.

(2)下面的程序执行后,ax和bx中的数值为多少

assume cs:codesg

stack segment

dw 8 dup(0)

stack ends

codesg segment

start:

mov ax, stack

mov ss, ax

mov sp,10h

mov word ptr ss:[0],offset s ;(ss:[0])=1ah

mov ss:[2],cs ;(ss:[2])=cs

call dword ptr ss:[0] ;cs入栈,ip=19h入栈,转到cs:1ah处执行指令

; ss:[0ch] = 19h ss:[0eh] = cs

nop

s: mov ax, offset s ;ax=1ah

}

sub ax, ss:[0ch] ;ax=1ah-(ss:[0ch])=1ah-19h=1

mov bx, cs ;bx=cs=0c5bh

sub bx, ss:[0eh] ;bx=cs-cs=0

mov ax,4c00h

int 21h

codesg ends

end start

相关文档