汇编语言与接口技术(第4版)清华大学出版社 第3章 80*86指令系统和寻址方式 课后题答案
答案有部分自己写的,如有错误还请指正,感谢。
1. 已知 DS=2000H,BX=0100H,SI=0002H,存储单元[20100H]~[20103H]依次存放12 34 56 78H,[21200H]~[21203H]依次存放 2A 4C B7 65H,说明下列每条指令执行后 AX寄存器的内容。
(1) MOV AX, 1200H
1200H 立即数寻址
(2) MOV AX, BX
0100H 寄存器寻址
(3) MOV AX, [1200H]
直接寻址
将内存偏移地址1200H处存储的数据存入AX中。按照:“数据段的段地址DS左移4位二进制位后+偏移地址 = 物理地址”的计算公式,可知[1200H]实际对应的物理地址是21200H
DS=2000H, 2000H*10H+1200H=21200H. 21200H=2A
因此这条指令就是将(21200H)存储的值赋给AL,将(21201H)存储的值赋给AH,所以执行这条指令后,AX的值是4C2AH
(4) MOV AX, [BX]
寄存器间接寻址
将BX寄存器中的数值0100H读出来,并以0100H为偏移地址,访问对应该偏移地址0100H的内存区域,即访问物理地址20100H。并将该内存区域(20100H)存储的数12H读出来,将12H赋给AL,再把(20101H)存储的数34H读出来并赋给AH,所以执行这条指令后,AX的值是3412H
(5) MOV AX, [BX+1100H]
这条指令使用了相对基址寻址,计算方法:“DS段地址左移4个二进制位+BX中存储的数值+1100H =物理地址”。
计算得到的物理地址是20000H+0100H+1100H = 21200H,所以应该将(21200H)存储的数值2A赋给AL,将(21201H)存储的数值4C赋给AH,所以执行这条指令后,AX的值是4C2AH
(6) MOV AX, [BX + SI]
这条指令使用了基址变址寻址,计算方法::“DS段地址左移4个二进制位+BX中存储的数值+SI中存储的数值 =物理地址”。计算得到的物理地址是20000H+0100H+0002H = 20102H,所以应该将(20102H)存储的数值56H赋给AL,将(20103H)存储的数值78H赋给AH,所以执行这条指令后,AX的值是7856H
(7) MOV AX, [BX][SI+1100H]
这条指令使用了相对基址变址寻址,计算方法:“DS段地址左移4个二进制位+BX中存储的数值+SI中存储的数值+1100H =物理地址”。计算得到的物理地址是20000H+0100H+0002H+1100H = 21202H,所以将(21202H)存储的数值B7H赋给AL,将(21203H)存储的数值65H赋给AH,所以执行这条指令后,AX的值是65B7H
2. 指出下列指令的错误。
(1) MOV CX, DL
两操作数长度不一致
(2) MOV IP, AX
目的操作数不能为IP
(3) MOV ES, 1234H
立即数不能直接送段寄存器
(4) MOV ES, DS
两个段寄存器之间不能直接进行数据传送
(5) MOV AL, 300H
两操作数长度不一致
(6) MOV [SP], AX
SP不能用作间址寄存器
(7) MOV AX, BX+DI
BX+DI改为[BX][DI]或[BX+DI]
(8) MOV 20H, AH
目的操作数不能为立即数
3.已知数字0~9对应的格雷码依次为 18H, 34H, 05H, 06H, 09H, 0AH, 0CH, 11H, 12H, 14H,它存在于以 TABLE 为首地址(设为 200H)的连续区域中。为如下程序段的每条指令加上注释,说明每条指令的功能和执行结果。
LEA BX, TABLE ;bx=0200H
MOV AL, 8 ;al=8
XLAT ;al=12H (上文所提到的8的格雷码)
在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray
Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。
典型的二进制格雷码(Binary Gray Code)简称格雷码。 我就单纯把它当成一个二进制码了
取有效地址指令LEA,将有效地址(这里指地址偏移值)送通用寄存器,而不是将存储单元的内容送通用寄存器。大多时候能与MOV混用。
XLAT表转换指令,以转换表中的一个字节来替换AL寄存器中的内容,可用于码的转换。其中DS:BX指向转换表的首址,转换前AL内容为序号,转换后AL内容为对应的码。
XLAT ;AL<-DS:((BX)+(AL))
4.什么是堆栈?它的工作原则是什么?它的基本操作有哪两个?对应哪两种指令
PUSH src
POP dest
堆栈是一种按“先进后出”原则存取数据的存储区域,位于堆栈段中,使用SS段寄存器记录其段地址;它的工作原则是先进后出;堆栈的两种基本操作是压栈和出栈,对应的指令是PUSH和POP。
5.已知SS=FFAOH,SP=00B0H,画图说明执行下面指令序列时堆栈区和SP的内容如何变化
MOV AX, 8057H
PUSH AX
MOV AX, 0F79H
PUSH AX
POP BX
POP [Bx]
“8057H〞进栈,那么SP自动从00B0H指向00B2H
“0F79H〞进栈,那么SP自动从00B2H指向00B4H;
执行一条POP指令,“0F79H〞被弹出栈,SP从00B4H指向00B2H
6.给出下列各条指令执行后 AL的值以及 CF、ZF、SF、OF和 PF的状态
MOV AL, 89H ;al=89H,其他的不变,单纯“赋值”而已,MOV指令不影响标志位
ADD AL, AL ;al=12H, CF=1, ZF=0, SF=0, OF=1, PF=1, AF=1
;1000 1001
;1000 1001
;01 0001 0010
ADD AL, 9DH ;AL=0AFH 0 0 1 0 1
;0001 0010
;1001 1101
;1010 1111
CMP AL, 0BCH ;AL=0AFH 1 0 1 0 1
;1010 1111
;-1011 1100
;0100 0011
SUB AL, AL ;AL=00H 0 1 0 0 1
DEC AL ;AL=0FFH 0 0 1 0 1
;0000 0000
;0000 0001
;*1111 1111
INC AL ;AL=00H 0 1 0 0 1
;1111 1111
;+0000 0001
;*1111 1111
进位标位CF:当运算结果的最高位有进位或借位时,进位标志置1,CF=1;否则CF=0;
零标志ZF:若运算结果为0,则ZF=1;否则ZF=0; 符号标志SF:若运算结果最高位为1,则SF=1;否则SF=0;
奇偶标志PF:当运算结果最低字节中“1”的个数为偶数时,PF=1;否则PF=0; 溢出标志OF:若算术运算的结果有溢出,则OF=1;否则OF=0;
SUB:不带借位的减法指令
INC:加1指令。这条指令一般用于循环程序的指针修改,INC指令只有一个操作数
DEC:减1指令。只有一个操作数,操作数可以为寄存器或者存储单元,不能为立即数。该指令实现将操作数中的内容-1,又叫减量指令
CMP:比较指令。将目的操作数与源操作数相减,不送回结果,只根据结果置标志位。CMP dest src ;(dest)-(src)
7.设 X,Y,Z 均为双字数据,分别存放在地址为X和 X+2、Y和 Y+2、Z和Z+2存储单元中,它们的运算结果存入单元。阅读如下程序段,给出运算公式
MOV AX, X ;AX=X
MOV DX, X+2 ;DX=X+2
ADD AX, Y ;AX=AX+Y=X+Y
ADC DX, Y+2 ;DX=DX+Y+2=X+2+Y+2
ADD AX, 24 ;AX=AX+24=X+Y+24
ADC DX, 0
SUB AX, Z ;AX=AX-Z=X+Y-Z+24
SBB DX, Z+2
MOV W, AX
MOV W+2, DX
运算公式:W=X+Y+24-Z
8.请分别用一条汇编语言指令完成如下功能:
(1)把 BX寄存器和DX寄存器的内容相加,结果存入DX寄存器。
ADD DX, BX
(2)用寄存器 BX和 SI的基址变址寻址方式把存储器的一个字节与 AL 寄存器的容相加,并把结果送到 AL中。
ADD AL, [BX+SI]
(3)用BX和位移量0B2H的寄存器相对寻址方式把存储器中的一个字和 CX寄器的内容相加,并把结果送回存储器中。
ADD [BX+0B2H],CX
(4)把数0A0H与AL寄存器的内容相加,并把结果送回 AL中
ADD AL, 0A0H
9.指出下列指令的错误。
(1) XCHG [SI], 30H
XCHG指令的操作数不允许是立即数
(2) POP CS
POP指令不允许使用CS
(3) SUB [SI], [DI]
两操作数不能同时是存储器寻址方式
(4) PUSH AH
堆栈的操作必须以字为单位
(5) ADC AX, DS
段寄存器不允许直接参加运算
10.给出下列各条指令执行后的结果,以及 CF、OF、SF、ZF、PF 的状态值
MOV AX, 1470H ;ax=1470h
AND AX, AX ;ax=1470h, CF=0, ZF=0, SF=0, OF=0, PF=0
OR AX, AX ;ax=1470h, CF=0, ZF=0, SF=0, OF=0, PF=0
XOR AX, AX ;ax=0000h, CF=0,ZF=0,SF=0,OF=1,PF=1
NOT AX ;ax=0ffffh, CF=0,ZF=0,SF=0,OF=1,PF=1
TEST AX, 0F0F0H ;ax=0ffffh, CF=0,ZF=0,SF=1,OF=0,PF=1
逻辑运算指令包括AND、OR、XOR、NOT和TEST指令。
指令格式:
AND dest,src ;dest←(dest)∧(src)
OR dest,src ;dest←(dest)∨(src)
XOR dest,src ;dest←(dest)⊕(src)
NOT reg/mem ;reg/mem←0FFFFH−(reg)/(mem)
TEST dest,src ;(dest)∧(src)
11.编写程序段完成如下要求:
(1)用位操作指令实现 AL(无符号数)乘以10
MOV BL, AL
MOV CL, 3
SHL AL, CL ;左移三位,相当于*8
ADD AL, BL ;已经乘过8了,再加一次自己相当于*9;
ADD AL, BL ;再加一次自己就相当于*10
SHL为逻辑左移指令,逻辑作业一次或CL指定的次数,与SAL相同。
SHR为逻辑右移指令,逻辑右移一次或CL指定的次数
(2)用逻辑运算指令实现数字 0~9 的 ASCII码与非压缩 BCD码的互相转换
方法一:
and al,0fh ;实现ASCII到非压缩BCD码的转换
or al,30h ;实现非压缩BCD码到ASCII的转换
方法二:
xor al,30h ;求反D5D4位,其他不变
;即高4位为3,则变为0;高4位为0,则变为3
1、BCD码同时也叫二进码十进数,通俗点就是用4位二进制数来表示0~9这10个十进制数,BCD码可以分为有权码和无权码,这里用最常见的8421BCD码来实现。非压缩BCD码的0~9是:00h~09h
2、ASCII码:查看ASCII码表可以知道0-9这10个二进制数在ASCII码中分别用16进制数30H~39H来表示
(3)把 DX、AX中的双字右移4位
MOV DX, 0FFFFH
MOV CL, 4 ;设置循环次数为4
SHR AX, CL ;实现将AX逻辑右移
MOV BL, DL ;将DL的低4位暂存在BL中
SHR DX, CL ;实现将DX逻辑右移
SHL BL, CL ;将BL逻辑左移
OR AH, BL ;将BL或上AH
;也就是使DL的低4位或上AH高4位,从而实现了DX、AX中的双字右移四位。
mov ax, 4c00H
int 21H
12.指令指针IP是通用寄存器还是专用寄存器?有指令能够直接对它赋值吗?哪类指令的执行会改变它的值?在调试程序DEBUG环境下如何改变IP数值?
指令指针IP不是通用寄存器,不可直接赋值,属于专用寄存器。
有且仅有循环、转移、子程序调用和返回、中断类等指令可以改变它的值。
13.按下述要求分别给出3 种方法,每种方法只用一条指令。
(1)使CF=0。
clc
add ax,0
sub ax,0
处理器指令-清进位位指令CLC ,即CF←0
(2)使AX=0。
mov ax,0
xor ax,ax
and ax,0
对AX寄存器清零的几条指令
1、AND AX,AX,可以对AX清零,还可以清除进位位和影响到SF、ZF、PF标志位。
2、mov ax,0 , 此条指令占用3个字节。
3、sub ax,ax , 减法指令, 该条指令只占用2个字节。
4、xor ax,ax
(3)同时使AX-0和CF=0
and ax,0
xor ax,ax
sub ax,ax
14.控制转移类指令中有哪几种寻址方式?
控制转移类指令分为: 无条件转移指令、 条件转移指令及调用和返回指令。
转移指令:可以修改IP,或者同时修改CS和IP的指令 称为转移指令。
控制转移指令包括如JMP、JZ、JB、LOOP、CALL、RET、INT、INTO、IRET等
15.什么是短转移、SHORT近转移、NEAR和远转移 FAR?什么是段内转移和段间转移?
只修改IP时,称为段内转移,段内转移根据IP的修改范围又分为短转移(short)和近转移(near);
短转移IP的修改范围为8位补码表示的范围:-128 ~ 127。
近转移IP的修改范围为16位补码表示的范围:-32768~32767(向前为负,向后为正)
同时修改IP和CS时,称为段间转移,又称远转移(far)。
段内转移和段间转移
转移指令:控制cpu执行内存中的某行代码,可以通过修改IP或者同时修改cs:ip
只修改IP的称为段内转移:jmp ax 相当于 mov ax,ip jmp ax
同时修改cs:ip的叫段间转移:jmp 1000:0(这是debug语法,只能在debug中使用)
转移指令分类:
-
无条件转移指令,jmp,其他转移指令大多可以基于jmp写出
-
有条件转移指令,jcxz
-
循环转移指令,loop
-
过程
-
中断
16.假设 DS=2000H,BX = 1256H,SI= 528FH,位移量 TABLE = 20A1H.[232F7H]=3280H,[264E5H]=2450H,执行下列段内间接寻址的转移指令后,转移的目的地址是什么?
(1)JMP BX
1256H
(2)JMP TABLE[BX]
3280H
(3)JMP [BX][SI]
2450H
17.设XYZV均为16 位带符号数,分别装在XYZV存储单元中阅读以下程序段,得出它的运算公式,并说明运算结果存于何处。
MOV AX, X
IMUL Y
MOV CX, AX
MOV BX, DX
MOV AX, Z
CWD
ADD CX, AX
ADC BX, DX
SUB CX, 540
SBB BX, 0
MOV AX, V
CWD
SUB AX, CX
SBB DX, BX
IDIV X
计算公式: [V-(X*Y+Z-540)]-X计算结果: 商存在AX中,余数存在DX中。
adc是带进位加法指令,它利用了CF位上记录的进位值。
指令格式:adc 操作对象1,操作对象2
功能:操作对象1=操作对象1+操作对象2+CF
sbb是带借位减法指令,它利用了CF位上记录的借位值。
指令格式:sbb 操作对象1,操作对象2
功能:操作对象1=操作对象1-操作对象2-CF
都是利用上一次改变CF位之后的结果加入到这次的运算。
针对程序就是
add cx,ax//影响下面结果CF
adc bx,dx
sub ax,cx//影响下面结果CF
sbb dx,bx
而dx是ax的符号拓展位,则相应的bx 是cx的符号拓展位。
这是将两个大数的加减用两个寄存器表示一个数。所以这需要在低位算过了之后用带位的加减法处理符号拓展位。
imul Y ;dx,ax = A*B (将操作数看作符号数,以下同)
IMUL:带符号的乘法指令。完成2个带符号的8位或16位二进制数乘法计算
CWD: 子扩展双字指令。将AX中的单字节数的符号扩展到DX中。若AX<8000H,则0->DX;若AL>=8000H,则FFFFH->DX 。这里将16位的带符号数Z扩展成32位,必须这样用
IDIV: 带符号除法指令
imul Y ;dx,ax = A*B (将操作数看作符号数,以下同)
18.已知AL=F7H(表示有符号数-9),分别编写用SAR和IDIV 指实现除以2的程序段,并说明各自执行后所得的商是什么。
(1)用sar编写
mov al,0f7h ;-9送AL 1111 1001
sar al,1 ;结果:AL=1111 1100B=0FBH 即-5
算术移位指令
指令格式: SAL reg/mem,1/CL SAR reg/mem,1/CL
要求:
reg为8位或16位通用寄存器,mem为8位或16位存储单元。
指令功能:SAL为算术左移指令,算术左移1次或CL指定的次数。SAR为算术右移指令,算术右移1次或CL指定的次数。
(2)用idiv编写
mov al,0f7h ; -9送al cbw
; 字节符号扩展位字
mov bl,2 ; 注意除数不可为立即数
idiv bl ; 结果:商为al=fch (-4) ; 余数:ah=ffh (-1)
结论:符号数的除法用idiv 准确。
带符号除法指令
格式:IDIV src IDIV dest,src
要求:dest目的操作数可为8位、16位通用寄存器或存储单元,src源操作数可为8位、16位通用寄存器、存储单元或立即数,但dest,src不能同为存储器。
指令功能:IDIV指令用于两个带符号数相除,其功能和对操作数长度的要求与DIV指令类似,本指令执行时,将被除数、除数都作为带符号数,其相除操作和DIV相同。
19.已知AXBX存放的是4位压缩 BCD码表示的十进制数,请说明如下程序段的功能。
ADD AL,BL
DAA
XCHG AL,AH
ADC AL,BH
DAA
XCHG AL,AH
RET
题中用了高地位交换,就是将两个BCD码相加
BCD调整指令分为两类,即组合的和未组合的BCD调整指令。
组合的BCD调整指令
指令格式:
DAA
DAS
第一条指令对在AL中的和(由两个组合的BCD码相加后的结果)进行调整,产生一个组合的BCD码;
第二条指令对在AL中的差(由两个组合的BCD码相减后的结果)进行调整,产生一个组合的BCD
交换指令 XCHG
指令格式:XCHG dest,src ;dest←→src
指令功能:XCHG指令用于交换两个操作数。
这条指令实际上起到了三条MOV指令的作用,指令中的两个操作数可以是两个寄存器操作数或一个寄存器与一个存储器操作数。
交换指令可实现通用寄存器之间、通用寄存器与存储单元之间的数据(字节或字)交换。
RET指令
通常作为一个子程序的最后一条指令,用以返回到调用子程序的断点处,即从堆栈弹出断电送往ip和cs寄存器
20.AAD 指令用于在除法指令之前进行非压缩 BCD 码调整。实际上,处理器的整过程是:AL<-AH * 10+AL,AH<-0。如果指令系统没有 AAD 指令,请编写程序段完成这个调整工作。
Htoasc proc
Mov bl,al
Mov al,ah
Mov bh,10
Mul bh
And ax,00ffh
Add al,bl
Htoend : ret
Htoasc endp
aadp proc
push bx
shl ah,1
mov bl,ah
shl ah,1
shl ah,1
add bl,ah
add al,bl
mov ah,0
pop bx
ret
aadp endp