第3章 8086的寻址方式和指令系统 (3) - USTC
Transcript of 第3章 8086的寻址方式和指令系统 (3) - USTC
2015年3月26日星期四11时3分17秒 1
第3章8086的寻址方式和指令系统
(3)
2015年3月26日星期四11时3分17秒 2
3.3.2 算术运算指令
数据类型:无符号和有符号整数。
无符号数又分成:
无符号二进制数;
无符号压缩十进制:1字节表示2个十进制数;
无符号非压缩十进制:1字节表示1个十进制数。
有符号数:有符号二进制数。用补码表示。
2015年3月26日星期四11时3分17秒 3
3.3.2 算术运算指令
2015年3月26日星期四11时3分17秒 4
3.3.2 算术运算指令
对加减法指令,无符号和有符号数可采用同一套指令,但应注意:
参加的操作数必须都是无符号数或都是有符号数。
需使用不同的标志位来检查无符号数和有符号数的运算结果是否溢出(第一章已述)。
2015年3月26日星期四11时3分17秒 5
两个8位数相加时有4种情况:
①无符号数和有符号数均不溢出
二进制相加 无符号数加 有符号数加0000 1000 8 +8
+0001 1110 + 30 + (+30)0010 0110 38 +38
结果38 CF=0 OF=0
2015年3月26日星期四11时3分17秒 6
② 无符号数溢出
0000 1000 8 +8
+1111 1101 +253 +(-3)
1 0000 0101 261 +5
结果5 CF=1 OF=0
2015年3月26日星期四11时3分17秒 7
③ 有符号数溢出
0000 1000 8 +8
+0111 1101 +125 +(+125)
1000 0101 133 +133
结果-123 CF=0 OF=1
(补码表示)
2015年3月26日星期四11时3分17秒 8
④ 无符号数和有符号数均溢出
1000 1000 136 -120
+1111 0111 +247 +(-9)
1 0111 1111 383 -129
结果127 CF=1 OF=1
2015年3月26日星期四11时3分17秒 9
上面四种情况说明:
CF标志可用来表示无符号数的溢出;
OF标志可用来表示有符号数的溢出。
2015年3月26日星期四11时3分17秒 10
指令系统提供加、减、乘、除四种基本运算指令,还有各种调整指令,见表3.6。
2015年3月26日星期四11时3分17秒 11
共有5条:
ADD/ADC/INC/AAA/DAA
1.加法指令
2015年3月26日星期四11时3分17秒 12
1) 不带进位的加法指令ADD
格式:
ADD acc,data
ADD mem/reg, data
ADD mem/reg1, mem/reg2 ; 不能同时为存储器
指令功能:目的←源+目的
ADD指令对标志位(指状态标志)有影响。
2015年3月26日星期四11时3分17秒 13
例
ADD AL,30H
ADD AX,[BX+20H]
ADD CX,SI
ADD [DI],200H
ADD AL,COST[BX]
;将AL内容和物理地址=DS:(COST+BX)的存储字节
;相加,结果送到AL中
2015年3月26日星期四11时3分17秒 14
2) 带进位位的加法指令ADC
格式:ADC acc, data
ADC mem/reg, data
ADC mem/reg1, mem/reg2
指令功能:目的←源+目的+CF
ADD/ADC操作数:它们的源操作数可以是寄存器、存储器或立即数。
目的操作数只能用寄存器和存储单元,存储单元可以为58页表3.2中所示的24种表示方法之一。
源和目的操作数不能同时为存储器,而且它们的类型必须一致,即都是字节或字。
2015年3月26日星期四11时3分17秒 15
2) 带进位位的加法指令ADC
例如:
ADC AL,68H ;AL←(AL)+68H+(CF)
ADC AX,CX ;AX←(AX)+(CX)+(CF)
ADC BX,[DI] ;BX←(BX)+[DI+1][DI]+(CF)
CF加到那个位置?
2015年3月26日星期四11时3分17秒 16
ADD/ADC对状态标志位(CF/OF/ZF/SF)的影响:
CF位表示无符号数加的溢出。
OF位表示带符号数加的溢出。
1 结果为负
0 否则SF=
1 和的最高有效位有向高位的进位
0 否则CF=
1 两个操作数符号相同,而结果符号与之相反
0 否则OF=
1 结果为0
0 否则ZF=
2015年3月26日星期四11时3分17秒 17
例 有两个4字节的无符号数相加:
2C 56 F8 AC+30 9E 47 BE=?
设被加数、加数分别存放在BUFFER1及BUFFER2开始的两个存储区内,结果放回BUFFER1存储区,如下页图所示。
ADC指令主要用于多字节加法运算中
2015年3月26日星期四11时3分17秒 18
56H
2CH
BEH
47H
BUFFER1
BUFFER2
ACH
F8H
9EH
30H
被加数
加数
数据段
...
因CPU只能进行8位或16位的加法运算,为此可将加法分4(2)次进行。
2015年3月26日星期四11时3分17秒 19
程序段如下:MOV CX,4 ;置循环次数MOV SI,0 ;置SI初值为零CLC ;清进位标志CF
LL: MOV AL,BUFFER2[SI]ADC BUFFER1[SI],AL ;带进位加INC SI ;(SI)+1DEC CX ;(CX)-1JNZ LL ;若(CX)≠0,则转LL
2015年3月26日星期四11时3分17秒 20
例 试用加法指令对两个8位16进制数5EH和3CH求和,分析指令执行后对标志位的影响。
程序如下:
MOV AL,5EH ;AL=5EH (94)
MOV BL,3CH ;BL=3CH (60)
ADD AL,BL ;结果AL=9AH
相加过程的算式表示:
0101 1110+ 0011 1100
1001 1010
2015年3月26日星期四11时3分17秒 21
运算后的标志位:
ZF=0,运算结果非0;AF=1,低4位向高4位有进位;CF=0,D7位没有向前产生进位C7;SF=1,D7=1;PF=1,结果中有偶数个1;OF=1,由两个数以及它们结果的符号决定,当两个加数符号相同,而结果的符号与之相反时,OF=1。
2015年3月26日星期四11时3分17秒 22
格式:INC opr;目的操作数,为reg/mem
功能:类似于C语言中的++操作:对指定的操作数加1
功能:opr←(opr)+1
例: INC AL
INC SI
INC BYTE PTR[BX+4];须说明数据类型
INC WORD PTR[BX]
注:本指令不影响CF标志。
3) 增量指令INC(单操作数指令)
2015年3月26日星期四11时3分17秒 23
1) 减法指令SUB格式: SUB dest, src功能: dest←(dest)-(src)
注:1.源和目的操作数不能同时为存储器操作数2.立即数不能作为目的操作数
指令例子:SUB AL, 60HSUB [BX+20H], DXSUB AX, CX
2. 减法指令
2015年3月26日星期四11时3分17秒 24
SBB指令主要用于多字节的减法。
格式: SBB dest, src
功能: dest←(dest)-(src)-(CF)
指令例子:
SBB AX, CX
SBB WORD PTR[SI], 2080H
SBB [SI], DX
2) 带借位的减法指令SBB
2015年3月26日星期四11时3分17秒 25
例:x、y、z均为32位数,分别存放在地址为X,X+2;Y,Y+2;Z, Z+2的存储单元中,用指令序列实现wx+y+24-z,结果放在W, W+2单元中。
2015年3月26日星期四11时3分17秒 26
MOV AX, XMOV DX, X+2ADD AX, YADC DX, Y+2 ; x+yADD AX, 24ADC DX, 0 ; x+y+24SUB AX, ZSBB DX, Z+2 ; x+y+24-zMOV W, AXMOV W+2, DX ; 结果存入W, W+2单元
2015年3月26日星期四11时3分17秒 27
作用类似于C语言中的“--”操作符。
格式:DEC opr;目的操作数
功能:opr←(opr)-1
(不影响CF位)
指令例子:
DEC CL
DEC BYTE PTR[DI+2]
DEC SI
DEC WORD PTR[BP] ;堆栈段中位于[BP]
;偏置处的字减1
3) 减量指令DEC
2015年3月26日星期四11时3分17秒 28
格式: NEG opr功能: opr← 0-(opr)
对一个操作数取补码相当于用0减去此操作数,故利用NEG指令可得到负数的绝对值。
4) 取负指令NEG
2015年3月26日星期四11时3分17秒 29
例:若(AL)=0FCH,则执行 NEG AL后,
(AL)=04H,CF=1
本例中,0FCH为-4的补码,执行求补指令后,即得到4(-4的绝对值)。
2015年3月26日星期四11时3分17秒 30
SUB/SBB对标志位(CF/OF/ZF/SF)的影响
CF=1表示无符号数减法溢出。OF=1表示带符号数减法溢出。
NEG指令对CF/OF的影响
CF:操作数为0时,求补的结果使CF=0,否则CF=1。OF:字节运算对-128求补或字运算对-32768求补时OF=1,
否则OF=0。
1 被减数的最高有效位有向高位的借位
0 否则CF=
1 两个操作数符号相反,而结果的符号与减数相同
0 否则OF=
2015年3月26日星期四11时3分17秒 31
格式: CMP dest, src
功能: (dest)-(src)
执行两个操作数相减,但结果不送目标操作数,其结果状态影响标志位。
作用:主要用在希望比较两个数的大小,而又不破坏原操作数的场合。
指令举例:
CMP AL,0AH
CMP CX,SI
CMP DI,[BX+03]
5) 比较指令CMP
2015年3月26日星期四11时3分17秒 32
根据标志位来判断CMP的结果
1)根据ZF判断两个数是否相等。若ZF=1,则两数相等。
2)若两个数不相等(ZF=0),则分两种情况考虑:
①比较的是两个无符号数
若CF=0(无借位),则dest>src;
若CF=1(有借位),则dest<src。
②比较的是两个有符号数
若OF⊕SF=0,则dest>src;
若OF⊕SF=1,则dest<src。
2015年3月26日星期四11时3分17秒 33
比较指令在使用时,一般在其后紧跟一个条件转移指令,判断比较结果的转向。举例:比较AL、BL、CL中带符号数的大小,将最小数放在AL中。
程序:CMP AL, BL ;AL和BL比较JNG BBB ;若AL≤BL,则转XCHG AL, BL ;若AL>BL,则交换
; 交换后AL存较小值BBB: CMP AL, CL ;AL和CL比较
JNG CCC ;若AL≤CL,则转XCHG AL, CL ;若AL>CL,则交换
CCC:HLT
2015年3月26日星期四11时3分17秒 34
乘法时:
8位*8位→16位乘积
16位*16位→32位乘积
3. 乘法指令
2015年3月26日星期四11时3分17秒 35
1) 无符号数的乘法指令MUL
格式: MUL src ; mem/reg功能:字节操作数 (AX) (AL) × (src)
字操作数 (DX, AX) (AX) × (src)隐含寻址:被乘数存放AL/AX
乘积分别存放AX/DX和AX指令例子:
MUL BL ; (AL)×(BL),乘积在AX中MUL CX ; (AX)×(CX),乘积在DX(高16位)
,AX(低16位)中MUL BYTE PTR[BX]
3. 乘法指令
2015年3月26日星期四11时3分17秒 36
格式与MUL指令类似,要求两操作数均为有符号数。
指令例子:
IMUL BL ;(AX)←(AL)×(BL)
IMUL WORD PTR[SI];
(DX,AX)←(AX)×([SI+1][SI])
2) 有符号数乘法指令IMUL
2015年3月26日星期四11时3分17秒 37
注意:MUL/IMUL指令中
● AL(AX)为隐含的乘数寄存器;● AX(DX,AX)为隐含的乘积寄存器;● src不能为立即数;●除CF和OF外,对其它标志位无定义。
2015年3月26日星期四11时3分17秒 38
乘法指令对CF/OF的影响:标志位的组合状态
00 乘积的高一半为零
11 高一半不为零MUL指令: CF/OF =
00 乘积的高一半是低一半的符号扩展
11 高一半是积的一部分IMUL指令: CF/OF =
例:(AL) = A5H(-5B),(BL) = 11H
(1) IMUL BL ; (AX) (AL)×(BL)
; A5×11 -5B×11= - 060B F9F5
; (AX) = F9F5H CF=OF=1
(2) MUL BL ; (AX) (AL)×(BL)
; A5×11= 0AF5
; (AX) = 0AF5H CF=OF=1
2015年3月26日星期四11时3分17秒 39
4. 除法指令
进行除法时: 16位/8位→8位商
32位/16位→16位商
对被除数、商及余数存放有如下规定:
被除数 商 余数
字节除法 AX AL AH
字除法 DX,AX AX DX
被除数AX(DX,AX)是隐含寻址,商AL/AX、余数AH/DX也为隐含寻址
2015年3月26日星期四11时3分17秒 40
格式: DIV src
指令功能:对两个无符号二进制数进行除法操作。
操作:字节操作:(AL) (AX) / (src) 的商
(AH) (AX) / (src) 的余数
字操作:(AX) (DX, AX) / (src) 的商
(DX) (DX, AX) / (src) 的余数
指令例子:
DIV CL
DIV WORD PTR[BX]
注:若除数为零或AL中商大于FFH(或AX中商大于FFFFH),则CPU产生一个类型0(除法错)的内部中断。
1) 无符号数除法指令DIV
2015年3月26日星期四11时3分17秒 41
2) 有符号数除法指令IDIV
格式: IDIV src
功能与DIV类似。
商及余数均为有符号数,且余数符号总是与被除数符号相同。
2015年3月26日星期四11时3分17秒 42
注意: 对于DIV/IDIV指令
AX(DX,AX)为隐含的被除数寄存器。
AL(AX)为隐含的商寄存器。
AH(DX)为隐含的余数寄存器。
src不能为立即数。
对所有条件标志位均无定义或不确定。
2015年3月26日星期四11时3分17秒 43
3) 字节/字、字/双字转换指令
格式:CBW ;把AL的符号位(D7)复制到AHCWD ;把AX的符号位(D15)复制到DX
用途:用于有符号数的除法。指令执行后不影响标志位。
例如:(AL) = A7H,则执行CBW后,AH的内容为FFH。(AL)=1010 0111(AH)=1111 1111
2015年3月26日星期四11时3分17秒 44
除法运算要求被除数字长是除数字长的两倍,若不满足则需对被除数进行扩展,否则产生错误。
对于无符号数除法扩展,只需将AH或DX清零即可。
对有符号数而言,则是符号位的扩展。可使用前面介绍过的符号扩展指令CBW和CWD
关于除法操作中的字长扩展问题
2015年3月26日星期四11时3分17秒 45
例: 写出34H÷25H的程序段。
MOV AL, 34H
MOV BL, 25H
CBW ; AL的符号扩展到AH
IDIV BL ; 0034H÷25H,结果为
; 余数(AH)=0FH, 商(AL)=01H
2015年3月26日星期四11时3分17秒 46
5.BCD码运算的十进制调整指令
专用于对BCD码运算的结果进行调整
包括:AAA、DAA、AAS、DAS、AAM、AAD
均为隐含寻址,隐含的操作数为AL和AH
为何要对BCD码的运算结果进行调整?
因为,BCD码(包括ASCII码)本质上是十进制数,即应遵循逢十进一的规则。
计算机是按二进制(十六进制)进行运算,并不按十进制规则进行运算。
2015年3月26日星期四11时3分17秒 47
1)加法的二进制-十进制调整指令
(1)非压缩BCD码加法调整AAA
指令格式:AAA
功能:本指令对由两个非压缩BCD(或ASCII)码操作数相加后在AL(隐含寻址)中的结果进行调整,得到一个正确的非压缩BCD码。
进位调整到AH(隐含寻址)中。
AAA指令只影响AF和CF,其余标志无定义。
AAA指令一般应紧跟在ADD或ADC指令之后。
2015年3月26日星期四11时3分17秒 48
如果AL的低4位>9或AF=1,则:
① AL←(AL)+6
② AL←((AL)∧0FH)
③ AF←1,CF←AF,AH←AF
否则(AL的低4位≤9或AF=0):
AL←(AL)∧0FH,即AL高4位清0。
AAA指令的操作如下:
2015年3月26日星期四11时3分17秒 49
调整原理:先看一个例子
计算8+9 0000 1000
见右式 +0000 1001
计算机按二进制加,故0001 0001
这个1代表了2进制的16,而实际上如果按压缩BCD计算仅应代表10,即多进了6。
2015年3月26日星期四11时3分17秒 50
实际上当低4位的结果>9(即A~F之间)时,也应进行加6调整 (原因是逢十没有进位,故用加6的方法强行产生进位) 。
如对上例的结果进行加6:
0001 0001 11
+ 0000 0110 6
0001 0111 17
∧ 0000 1111
0000 0001 0000 0111
AAA
①
②
③
AX=0107H→
AH AL
2015年3月26日星期四11时3分17秒 51
例2:有两个字符串形式的十进制数,5678和
6789,求二者之和。即5678+6789=?
由题意知,被加数和加数的每一位都以ASCII码形式存放在内存中。
假定二数在内存中均是低位在前,高位在后,另留出5个字节单元存放相加的结果。
内存中数据存放形式见下页图。
2015年3月26日星期四11时3分17秒 52
36H
35H
39H
38H
STRING1
STRING2
38H
37H
37H
36H
被加数
加数
数据段
‘8’
‘7’
‘6’
‘5’
‘9’
‘8’
‘7’
‘6’
SUM
结果
......
2015年3月26日星期四11时3分17秒 53
程序,为:LEA SI,STRING1 ;STRING1偏移地址送SILEA DI,STRING2 ;STRING2偏移地址送DILEA BX,SUM ;SUM偏移地址送BXMOV CX,4 ;循环4次CLC ;清进位标志
AGAIN:MOV AL,[SI]ADC AL,[DI] ;带进位加AAA ;非压缩BCD码调正MOV [BX],AL ;结果存入SUMINC SI ;调整指针INC DIINC BXDEC CX ;循环计数器减1JNZ AGAIN ;若未处理完,则转AGAIN
2015年3月26日星期四11时3分17秒 54
课堂作业
为什么AAA指令既可对非压缩BCD码加法进行调整,也可对ASCII码形式的十进制数进行调整?
2015年3月26日星期四11时3分17秒 55
(2)压缩BCD码加法二-十进制调整DAA
指令格式: DAA
指令功能:对两个压缩BCD数相加后的结果(已在AL中)进行调整。
两个压缩BCD码相加结果在AL中,通过DAA调整得到一个正确的压缩BCD码。
指令操作(调整方法):
若AL的低4位>9∨AF=1
则(AL)←(AL)+6,AF←1
若AL的高4位>9∨CF=1
则(AL)←(AL)+60H,CF←1(否则置0)
除OF外,DAA指令影响所有其它标志。
DAA指令一般应紧跟在ADD或ADC指令之后。
2015年3月26日星期四11时3分17秒 56
例: 0100 1000 48H
MOV AL,48H + 0111 0100 74H
MOV BL,74H 1011 1100 BCH
ADD AL,BL
DAA + 0110 0110 + 66H
1 0010 0010 1 22HBCD
(进位)
执行ADD后,(AL)=BCH,高4位低4位均大于9,故DAA指令执行加66H调整,最后结果为:
(AL)=22H, CF=1, AF=1
2015年3月26日星期四11时3分17秒 57
(1)非压缩BCD码减法的十进制调整指令AAS
指令格式:AAS
指令功能:在用SUB或SBB指令,对两个非压缩BCD(ASCII)数表示的十进制数相减后,对AL中所得结果进行调整,如有借位,则CF置1。
调整操作为:若AL的低4位>9或AF=1,则:
① AL←(AL)-6,AF←1② AL←(AL)∧0FH③ AH←(AH)-1,CF←AF
否则:AL←(AL)∧0FH
2)减法的二进制-十进制调整指令
2015年3月26日星期四11时3分17秒 58
举例:16-8=?
MOV AX,0106H 0000 0110 06?
MOV BL,08H - 0000 1000 - 08
SUB AL,BL 1111 1110 FE
AAS - 0000 0110 - 06
1111 1000 F8
∧0000 1111 ∧0F
0000 1000 08
结果为:(AL)=08H,(AH)=0,CF=AF=1
2015年3月26日星期四11时3分17秒 59
(2)压缩BCD码减法的二进制-十进制调整指令DAS
指令格式: DAS
指令功能: 在用SUB或SBB指令,对两个压缩BCD数相减(结果已存在AL中)后,进行调整。
DAS对OF无定义,但影响其余标志位。
同样,它也要对AL中高半字节和低半字节分别进行调整。调整操作为:
若AL的低4位>9∨AF=1,则:AL←(AL)-6, AF←1
若AL的高4位>9∨CF=1,则:AL←(AL)-60H,CF←1
不举例,可见教材例,p77例3.55。
2015年3月26日星期四11时3分17秒 60
3) 乘法的二进制—十进制调整指令AAM指令格式:AAM指令功能:对存于AL的两个非压缩BCD数相乘的积进行调整,结果在AX中,高位放AH,低位在AL。如果两个ASCII码数相乘之前,应先屏蔽掉每个数的高半字节,即高半字节清零。
调整操作为:(AL)/0AH, (AH)←商,(AL)←余数
隐含的操作寄存器为AL和AH;AAM跟在MUL指令之后使用;影响标志位PF、SF、ZF,其它无定义;用AAM可实现≤99的二—十进制转换。
2015年3月26日星期四11时3分17秒 61
例1:按十进制乘法计算7×8=?
程序段如下:
MOV AL,07H ;(AL)=07H
MOV CL,08H ;(CL)=08H
MUL CL ;(AX)=0038H
AAM ;(AH)=05H,(AL)=06H
所得结果为非压缩的BCD码。
例2:把3AH转换成等值的十进制数。
MOV AL,3AH ;58
AAM ; (AH)=05H,(AL)=08H
2015年3月26日星期四11时3分17秒 62
4) 除法的十进制-二进制调整指令AAD
指令格式:AAD
指令功能:在做除法前把BCD(ASCII)码转换成二进制数。
对非压缩BCD除法运算进行二进制调整。调整操作为:
(AL)←(AH)×0AH+(AL)
AH ← 00H
隐含的操作寄存器为AH,AL;
AAD要在DIV指令之前使用;
影响标志位PF、SF、ZF,其它无定义;
用AAD可实现≤99的十-二进制转换。
2015年3月26日星期四11时3分17秒 63
例1:按十进制除法计算55÷7=?程序段如下:
MOV AX, 0505H ;(AX)=55BCD
MOV CL, 07H ;(CL)= 7AAD ;(AX)=0037H,即55的16进制数DIV CL ;余数(AH)=6, 商(AL)=7
所得结果为非压缩的BCD码(商7余6)。
例2:把73转换成等值的二进制数。MOV AX, 0703H ;(AX)= 73BCD
AAD ;(AX)= 0049H,即73的16进制数