乘除运算指令
8086/8088除了提供加减运算指令外,还提供乘除运算指令。乘除运算指令分为无符号数运算指令和有符号数运算指令,这点与加减运算指令不同。乘除运算指令对标志位的影响有些特别,不像加减运算指令对标志位的影响那样自然。
1. 乘法指令
在乘法指令中,一个操作数总是隐含在寄存器AL(8位数相乘)或者AX(16位数相乘)中,另一个操作数可以采用除立即书方式以外的一种寻址方式。
1)无符号数乘法指令MUL(MULtiply)
无符号指令的格式如下:
MUL OPRD
如果OPRD是字节操作数,则把AL中的无符号数语OPRD相乘,16位结果送到AX中;如果OPRD是字操作数,则把AX中的无符号数与OPRD相乘,32位结果送到DX和AX对中,DX含高16位,AX含低16位。所以由操作数OPRD决定是字节相乘,还是字相乘。例如:
MUL BL
MUL AX
MUL VARW ;VARW是字变量
如果乘积结果的高半部分(字节相乘时为AH,在字相乘时为DX)不等于零,则标志CF=1,OF=1;否则CF=0,OF=0。所以CF=1和OF=1表示在AH或DX中含有结果的有效数。该指令对其他标志位无定义。
2)有符号数乘法指令IMUL(slgned MULtiply)
有符号数乘指令的格式如下:
IMUL OPRD
这条指令把被乘数和乘数均作为有符号数,此外与指令MUL完全类似。例如:
IMUL CL
IMUL DX
IMUL VARW ;VARW是字变量
如果乘积结果的高半部分(字节相乘时为AH,在字相乘时为DX)不是低半部分的符号扩展,则标志CF=1,OF=1;否则CF=O,OF=0。所以CF=1和 OF=1表示在AH或DX中含有结果的有效数。该指令对其他标志位无定义。
2. 除法指令
在除法指令中,被除数总是在隐含在寄存器AX(除数是8位)或者DX和AX(除数是16位)中,另一个操作数可以采用除立即数方式外的任一种寻址方式。
1)无符号数除法指令DIV(DIVision)
无符号数除法指令的格式如下:
DIV OPRD
如果OPRD是字节操作数,则把AX中的无符号数除以OPRD,8位的商送到AL中,8位的余数送到AH;如果OPRD是字操作数,则把DX(高16位)和AX中的无符号数除以OPRD,16位的商送到AX,16位的余数送到DX中。所以由操作数OPRD决定是字节除,还是字除。例如:
DIV BL
DIV SI
DIV VARW ;VARW是字变量
注意:如果除数为0,或者在8位数除时商超过8位,或者在16位时商超过16位,则认为是除溢出,引起0号中断。
除法指令对标志位的影响无定义。
2) 有符号数除法指令IDIV(signed DIVision)
有符号数除法指令的格式如下:
IDIV OPRD
这条指令把被除数和除数均作为有符号数,此外与指令DIV完全类似。
例如:
IDIV CX
IDIV VARW ;VARW是字变量
当除数为0,或者商太大(字节除时超过127,字除时超过32767),或者商太小(字节除时小于—127,字除时小于—32767)时,则引起0号中断。
3. 符号扩展指令
由于除法指令隐含使用字被除数或双字被除数,所以当被除数为字节,或者除数和被除数均为字节时,需要在除操作前扩展被除数。为此8086/8088专门提供了符号扩展指令。
1)字节转换为字指令CBW(Convert Byte to Word)
字节转换为字指令的格式如下:
CBW
这条指令把寄存器AL中的符号扩展到寄存器AH。即若AL的最高有效位为0,则AH=0;若AL的最高有效位为1,则AH=0FFH。例如:
MOV AX,3487H ;AX=3487H,即AH=34H, AL=87H
CBW ;AH=0FFH,AL=87H,即AX=0FF87H
这条指令能在两个字节相除以前,产生一个字长度的被除数。这条指令不影响各标志位。
2) 字转换为双字指令CWD(Converta Word to Double word)
字转换为双字指令的格式如下:
CWD
这条指令把寄存器AX中的符号扩展到寄存器DX。即若(AX)的最高有效位为0。则DX=0;若AX的最高有效位为1,则DX=0FFFFH。
例如:
MOV AX,4567H ;AX=4567H
CWD ;AX=4567H, DX=0
这条指令能在两个字相除以前,产生一个双字长度的被除数。该指令不影响各标志位。
注意:在无符号数除之前,不宜用CBW或CWD指令扩展符号位,一般采用XOR指令清高8位或高16位。
例,计算如下表达式的值:
(X*Y Z-1024)/75
假设其中的X﹑Y和Z均为16位带符号数,分别存放在名为XXX﹑YYY和ZZZ的变量单元中。再假设计算结果的商保存在AX中,余数保存在DX中。下面的程序片段能够满足要求:
……
MOV AX,XXX
IMUL YYY 计算X*X
MOV CX,AX
MOV BX,DX ;积保存到BX:CX中
MOV AX,ZZZ
CWD ;把ZZZ扩展成32位
ADD AX,CX ;再计算和
ADC DX,BX
SUB AX,1024 ;再计算差
SBB DX,0
MOV CX,75
IDIV CX ;最后计算商和余数
……