与减法运算,常用于多字节减法运算。
例如:
SBB BL,30H ;(BL)←(BL)- 30H - CF SBB WORD PTR[SI],1034H ;(SI)+ 1和(SI)的两个单元的值减去立即数1034H ;及CF的值,结果送回(SI)+ 1及(SI)两个单元 (3)减1指令DEC(decrement) 指令格式为:
DEC OPRD ;(OPRD)←(OPRD)- 1
DEC指令将指定的操作数内容减1,后再送回该操作数。它对操作数的要求及对标志位的影响均与INC指令相同。
它也常在循环程序中用于修改地址指针及循环次数等。 例如: DEC DEC DEC 减
DEC指令应用举例:
例:编写一个延时程序。 MOV NEXT: DEC
CX,OFFFFH CX
;1,后送回该单元
AX BL
BYTE PTR[DI]
;(AX)←(AX)- 1 ;(BL)←(BL)- 1
;以ES内容为基址,以DI内容为偏移地址单元的内容
;送计数初值到CX
;计数值(CX内容)减1
JNZ NEXT ;若(CX)≠0,则转NEXT HLT ;停止
上程序延时时间可通过查表找到各条指令执行的时钟周期,后通过计算得到。 (4)求补指令NEG(negate) 指令格式为: NEG OPRD
;(OPRD)← 0 -(OPRD)
NEG指令的功能是对操作数求补。即用0减去操作数内容,并将结果送回该操作数。
NEG指令对6个状态标志位都有影响,并需注意以下两点:
①执行NEG指令后,除操作数位0外,一般情况下,都会使CF为1。
②当指定的操作数为80H(-128)或位8000H(-32768),则执行NEG指令后,结果不变,但此时OF置1,其它情况下OF均置0,
NEG指令应用举例:
例:设(DS)= 6000H,(BX)= 0010H,(60010H)= 47H。 试析执行NEG [BX]指令的结果。
解:执行上指令时,CPU将进行如下减法运算:
00000000 - 01000111 10111001
故执行后(60010H)= B9H,相当于对-47H求补。 (5)比较指令CMP(compare)
指令格式为:
CMP OPRD1,OPRD2 ;(OPRD1)-(OPRD2) CMP指令对两个操作数进行比较(相减),相减结果不送目标操作数,而根据相减的结
36
果影响标志位。指令对操作数的要求及对标志为的影响与SUB指令完全相同。
例如:
CMP BX,2100H CMP CL,DH
CMP AX,[BX+SI+4] 响
;(BX)- 2100H, 影响标志位
;(CL)-(DH), 影响标志位 ;(AX)-((BX)+(SI)+5):((BX)+(SI)+4)),影;标志位
比较指令主要用来比较两个数的大小关系。可在指令执行后,根据标志位的状态判断
两个操作数的大小,或是否相等。判断方法如下:
·相等关系:根据ZF状态判断。如ZF = 1,两个操作数相等。否则,不等。 ·大小关系:分无符号数和有符号数两种情况:
(1)对两个无符号数,可据CF状态来判断。如CF = 0,则被减数大于减数;如CF = 1, 则减数大于被减数。
(2)对两个有符号数,需考虑两个数是同号还是异号。
①对两个同符号数,相减不会产生溢出,即OF = 0。有: 若SF = 0,则被减数大于减数。
若SF = 1,则减数大于被减数。
②对两个不同符号数,相减可能产生溢出,也可能不产生溢出。 若OF = 0,(无溢出),则: 如被减数大于减数 SF = 0 如减数大于被减数 SF = 1
若OF = 1,(有溢出),则:
如被减数大于减数 SF = 1(例7FH - 82H = FDH) 如减数大于被减数 SF = 0(例82H - 7FH = 03H)
对上结果进行归纳,可得出判两个有符号数大小的方法是:
当OF⊕SF = 0时,被减数大于减数 当OF⊕SF = 1时,减数大于被减数
编程时,一般都在CMP指令后紧跟一条条件转移指令,以根据比较结果决定程序走向。
3.乘法指令
8088的乘法指令包括无符号数乘法指令(MUL)和有符号数乘法指令(IMUL)两种。采用隐含寻址方式,源操作数由指令给出,目标操作数隐含。当字节与字节相乘时,乘积为16位,规定存放在AX中;当字与字相乘时,乘积为32位,规定高16位存放在DX中,低16位存放在AX中。
(1)无符号数的乘法指令MUL(unsigned mutiple) 指令格式为: MUL
OPRD
指令操作分两种情况: 字节相乘:(AX)←(OPRD)×(AL)
字相乘:(DX):(AX)←(OPRD)×(AX)
指令中源操作数OPRD可为8位或16位寄存器操作数或存储器操作数,但不能为立即数。
例如: MUL BX
;(DX):(AX)←(AX)×(BX)
37
MUL BYTE PTR[SI] ;(AX)←(AL)×((SI))
MUL DL ;(AX)←(AL)×(DL)
MUL WORD PTR[DI] ;(DX):(AX)←(AX)×((DI) + 1):((DI)) MUL指令对CF及OF标志有影响,当乘积的高半部(在字节相乘时为AH,在字相乘时为DX)不为零,则CF = OF = 1,否则CF = OF = 0。对其它标志位无定义。
乘法指令执行时间较长,在某些场合下,可用左移指令来代替,以加快运行速度,待在移位指令中再作介绍。
(2)带符号数的乘法指令IMUL(signed mutiple) 指令格式为: IMUL OPRD
IMUL指令功能与MUL指令类似,仅有以下几点差别: ·两乘数都为有符号数。
·若乘积的高半部分是低半部分的扩展,则CF = OF = 0;否则,CF = OF = 1 ·指令中给出的源操作数应在带符号数的表示范围内。(作解释,如操作数为表达式) IMUL指令应用举例:
例:设(AL)= FEH,(CL)= 11H,求两数的乘积。
若将两数看作无符号数,则应使用指令: MUL CL 执行后结果:(AX)= 10DEH(解释:即0FE0H + FEH = 10DEH), 且CF = OF = 1(∵AH内容不为0)。 若将两数看作带符号数,则应使用指令:
IMUL CL 执行后结果:(AX)= FFDEH(解释:相当于-2×11H = -22H,即为FFDEH), 且CF = OF = 0(∵AH内容为AL内容符号位的扩展)。
4.除法指令
8088的除法指令也包括无符号除法指令(DIV)和有符号除法指令(IDIV)两种,也采用隐含寻址方式。除数由指令给出(不能为立即数)。
除法指令要求被除数的字长必须为除数的2倍(如不够要用字位扩展指令来扩展)。当除数为8位,则被除数为16位,规定放在AX中;当除数为16位,则被除数为32位,规定放在DX(高16位)和AX(低16位)中。
(1)无符号数的除法指令DIV(unsigned divide)
指令格式为: DIV OPRD
指令操作数OPRD可为8位或16位,寄存器或存储器操作数,但不可为立即数。 字节除法:(AL)←(AX)/(OPRD) (AH)←(AX)%(OPRD) (%为取余操作)
即AX中的16位无符号数除以OPRD的内容。得到8位的商放AL中,8位的余数放AH中。
字除法:(AX)←((DX):(AX))/(OPRD) (DX)←((DX):(AX))%(OPRD) (%为取余操作)
即以DX和AX中的32位无符号数除以OPRD的内容。得到16位的商放在AX中,16位的余数放在DX中。
若除法运算的结果大于寄存器可保存的最大值,即超出8位或16位无符号数可表示的
38
范围,则在CPU内部会产生1个类型0中断(以后再讲)。
例如:
DIV BL
DIV WORD PTR[SI]
;(AX)除以(BL),商放在AL,余数放在AH
;(DX):(AX)除以((SI) + 1):((SI)),商放在AX, ;余数放在DX
DIV指令应用举例:
例:用除法指令及所7FA2H÷03DDH。 程序如下:
MOV AX,7FA2H MOV CWD DIV
BX,03DDH BX
;(AX)= 7FA2H ;(BX)= 03DDH
;(DX):(AX)= 00007FA2H
;(AX)= 0021H(商),(DX)= 0025H(余数)
(2)有符号数的除法指令IDIV(singned divide)
指令格式为:
IDIV OPRD
IDIV指令与DIV在功能上类似,唯操作对象和结果均为有符号数。 例如: IDIV CX
IDIV BYTE PTR[BX] 商
;在AX中,余数在DX中
IDIV指令执行的结果,商和余数均为带符号数,但规定余数符号与被除数相同。以保证除法的结果为唯一(作说明,例见P.124)。
无符号除法和有符号除法对六个标志位均无影响。
5.BCD码(十进制数)运算调整指令
为实现十进制(BCD码)运算,8088提供了6条用于BCD码运算和调整指令。均采用隐含寻址方式,隐含操作数为AL(或AL和AH)。这些指令与加、减、乘、除指令配合,实现BCD码的算术运算。
1)加法的十进制调整指令
BCD码存放有压缩和非压缩两种形式,故加法的十进制调整也包括压缩和非压缩两种。 (1)压缩BCD码加法的十进制调整指令DAA(desimal adjust for addition) 指令格式为
DAA
DAA指令用于对两个压缩BCD码相加之和(结果在AL中)进行调整,以产生正确的压缩BCD码运算结果。调整方法为:
①若(AL)中低4位>9或AF = 1,则(AL)←(AL)+ 06H,并使AF = 1。 ②若(AL)中高4位>9或CF = 1,则(AL)←(AL)+ 60H,并使CF = 1。 DAA指令应用举例:
例:试编程,计算48 + 27 = ?(要求计算结果为压缩BCD码) 程序如下: MOV AL,48H ADD AL,27H
;DX和AX中的32位数除以(CX),商在AX中,余数在 ;DX中
;(AX)除以DS段以(BX)为偏移地址单元中的内容,
39
DAA
上第二条指令的计算过程为:
01001000 + 00100111 01101111 DAA指令调整过程为:
01101111
+ 00000110
01110101 (注意,如调整中出现半进位或进位,不再调整) 结果:(AL)= 75H,AF = 1,CF = 0。
DAA指令影响除OF以外的其余5个状态标志。
(2)非压缩BCD码加法的十进制调整指令AAA(ASCII adjust for addition) 指令格式为: AAA
AAA指令用于对两个非压缩BCD码数相加之和(结果在AL中)进行调整,形成一个正确的扩展BCD码,调整后,结果和的低位在AL中,高位在AH中。调整步骤为:
①若(AL)中低4位>9或AF = 1,则(AL)←(AL)+ 06H,(AH)+ 1,并使AF = 1。 ②屏蔽掉(AL)中的高4位,即(AL)←(AL)∧0FH。 ③CF←AF
AAA指令应用举例::
例:试编程,计算9 + 4 = ?(要求计算结果为非压缩BCD码) 程序如下: MOV AL,09H MOV BL,04H ADD AL,BL AAA
;BCD码数9送AL ;BCD码数4送BL ;(AL)= 09H + 04H = 0DH
;调整后,(AL)= 03H(即0DH + 06H)∧0FH = 03H,(AH)= 1, ;CF = 1
AAA指令只影响AF和CF标志。
注意:DAA和AAA指令都必须紧跟在ADD指令或ADC指令后执行,且ADD或ADC指令的执行结果都必须放在AL中。
2)减法的十进制调整指令
减法的十进制调整也分为压缩BCD码和非压缩BCD码两种。
(1)压缩BCD码减法的十进制调整指令DAS(desimal adjust for subtraction) 指令格式为
DAS
DAS指令用于对两个压缩BCD码数相减后的结果(在AL中)进行调整。产生正确的压缩BCD码运算结果。调整方法如下:
①若(AL)中低4位>9或AF = 1,则(AL)←(AL)- 06H,并使AF = 1。 ②若(AL)中高4位>9或CF = 1,则(AL)←(AL)- 60H,并使CF = 1。 DAS指令对标志位的影响与DAA指令相同。
(2)非压缩BCD码减法的十进制调整指令AAS(ASCII adjust for subtraction) 指令格式为 AAS
AAS指令用于对两个非压缩BCD码数相减后的结果(在AL中)进行调整。形成一个正
40