(字节相乘时为AH,在字相乘时为DX)不是低半部分的符号扩展,则标志CF=1,OF=1;否则否则CF=0,OF=0。所以如果CF=1和OF=1表示在AH或DX中含有结果的有效数。该指令对其他标志位无定义。
例如:如(AL)=0B4H,(BL)=11H求执行指令 IMUL BL
MUL BL后的乘积值。
执行IMUL BL的结果为(AX)=0FAF4H=-1292D CF=OF=1 有符号数用FFB4*11或转换成二进制,如果AX中的高半部分AH不是FF,这里是FA,则CF=OF=1。 执行MUL BL的结果为(AX)=OBF4H=3060D CF=OF=1 无符号数用B4*11 2.除法指令
在除法指令中,被除数总是隐含在寄存器AX(除数是8位)或者DX和AX(除数是16位)中,另一个操作数可以采用除立即数方式外的任一种寻址方式。 (1)无符号数除法指令DIV 格式:DIV OPRD
字节操作表示为:(AL)←(AX)/(OPRD)的商:(AH)←(AX)/(OPRD)的余数 字操作表示为:(AX)←(DX,AX)/(OPRD)的商;(DX)←(DX,AX)/(OPRD)的余数 如果除数为0,或者在8位数除时商超过8位。或者在16位除时商超过16位,则认为是除溢出,引起0号中断。除法指令对标志位的影响无定义。 (2)有符号数除法指令IDIV 格式:IDIV OPRD
这条指令把被除数和除数均作为有符号数,此外与指令DIV完全类似。当除数为0,或者商太大(字节除时超过127,字除时超过32767),或者商太小(字节除时小于-127,字除时小于-32767)时,则引起0号中断。
例如:设(AX)=0400H,(BL)=0B4H,即(AX)为无符号数的1024D,带符号数的1024D(BL)为无符号数的180D,带符号数的-76D 执行DIV BL的结果是: (AH)=7CH=124D余数 (AL)=05H=5D 商 执行IDIV BL的结果是: (AH)=24H=36D余数 (AL)=0F3H=-13D商 3.符号扩展指令
由于除法指令隐含使用字被除数或双字被除数,所以当被除数为字节,或者除数和被除数均为字
时,需要在除操作前扩展被除数。为此8086 8088专门提供了符号扩展指令。 (1)字节转换为字指令CBW 格式:CBW
这条指令把寄存器AL中的符号扩展到寄存器AH。
例如:MOV AX,3487H ;AX=3487H,即AH=34H,AL=87H
CBW ;AH=0FFH,AL=87H,即AX=0FF87H 这条指令不影响各标志位。 (2)字转换为双字指令CWD 格式:CWD
这条指令把寄存器AX中的符号扩展到寄存器DX。 例如:MOV AX,4567H ;AX=4567H
CWD ;AX=4567H,DX=0 该指令不影响标志位。
AL和AX中最高有效位是0~7位为正数,则AH和DX扩展为00; AL和AX中最高有效位是8~15位为负数,则AH和DX扩展为FF。 (四)逻辑运算和移位指令 1.逻辑运算指令 (1)否操作指令NOT 格式:NOT OPRD
这条指令把操作数OPRD取反,然后送回OPRD。操作数OPRD可以是通用寄存器,也可以是存储器操作数,不能是立即数。此指令对标志位没有影响。 例如:MOV AL,03H NOT AL 指令执行后:(AL)=0FCH (2)与操作指令AND 格式:AND OPRD1,OPRD2
这条指令对两个操作数进行按位的逻辑“与”运算,结果送到目的操作数OPRD1。该指令执行以后,标志CF=0,标志OF=0,标志PF、ZF、SF反映运算结果,标志AF未定义。某个操作数自己与自己相“与”,则值不变,但可使进位标志CF清0。与操作指令主要用在使一个操作数中的若干位维持不变,而另外若干位清为0的场合。把要维持不变的这些位于“1”相“与”,而把要清为0的这些位于“0”相“与”就能达到这样的目的。
相“与”:两个操作数都是1的,结果为1,其他情况全是0。 例如:MOV AL,23H
MOV BL,02H AND AL,BL 指令执行后:(AL)=02H
(AL)=23H,将AL寄存器的第一位和第三位清零,其余位不变,则BL是什么时,与AL执行AND指令可完成? (BL)=F5H MOV AL,23H MOV BL,F5H AND AL,BL (3)或操作指令OR 格式:OR OPRD1,OPRD2
这条指令执行以后,标志CF=0,标志OF=0.,标志PF、ZF、SF反映运算结果,标志AF未定义。某个操作数自己与自己相“或”,则值不变,但可使进位标志CF清0。 相“或”:两个操作数中有一个是1的,结果为1,其他情况全是0。
或操作指令主要用于在使一个操作数中的若干位维持不变,而另外若干位置为1的场合。把要维持不变的这些位于“0”相“或”,而把要置为1的这些位与“1”相“或”就能达到这样的目的。 例如:MOV BL,12H OR BL,BL
(BL)=12H CF=0 (4)异或操作指令XOR 格式:XOR OPRD1,OPRD2
相“异或”:两个操作数,一个是0,一个是1,则为1;两个都为1,则为0;两个都为0,则为0。 这条指令对两个操作数进行按位的逻辑“异或”运算,结果送到目的操作数OPRD1。该指令执行以后,标志CF=0,标志OF=0,标志PF、ZF、SF反映运算结果,标志AF未定义。某个操作数自己与自己相“异或”,则结果为0,并可使进位标志CF清0。异或操作指令主要用于在使一个操作数中的若干位维持不变,而另外若干位置取反的场合。把要维持不变的这些位于“0”相“异或”,而把要取反的这些位与“1”相“异或”就能达到目的。 例如:MOV BL,56H XOR BL,BL
指令执行后:(BL)=0 CF=0 (5)测试指令TEST 格式:TEST OPRD1,OPRD2
这条指令和指令AND类似,也把两个操作数进行按位“与”,但结果不送到操作数OPRD1。该指
令执行以后,标志ZF、PF和SF反映运算结果,标志CF和OF被清0。该指令通常用于检测某些位是否为1,但又不希望改变原操作数值的场合。
例如:要检查AL中的位6或位2是否有一位为1,可使用下面的指令: TEST AL,01000100B (44H)
如果位6和位2全为0,那么在执行上面的指令后,ZF被置1,否则ZF被清0。
例如:要测试操作数的某位是否为1,则可先把该操作数求反然后用TEST指令测试。如要测试AL寄存器中第二位是否为1,如为1则转移到EXIT去执行,可用下列指令序列: MOV DL,AL NOT DL
TEST DL,00000100B JE EXIT 2.一般移位指令
(1)算术左移或逻辑左移指令SAL/SHL
算术左移和逻辑左移进行相同的动作,尽管为了方便提供有两个助记符,但只有一条机器指令。 格式:SAL OPRD,m SHL OPRD,m
算术左移SAL(有符号数)/逻辑左移SHL(无符号数)指令把操作数OPRD左移m,每移动一位,右边用0补足一位,移出的最高位进入标志位CF。
例如:MOV AL,12H ;0001 0010B SHL AL,1 ;0010 0100B 指令执行后(AL)=24H (相当于乘以2) MOV AL,8CH ;1000 1100B SHL AL,1 ;0001 1000B 指令执行后(AL)=18H ,CF=1,PF=1,ZF=0,SF=0,OF=1
溢出标志OF是在移一位的时候有效,如果移动6位,8位,多位就无效。 MOV CL,6 SHL AL,CL
指令执行后(AL)=0,CF=0,PF=1,ZF=1,SF=0,OF=0
移位次数超过1的,一定要把移位次数放到CL里面去。只要左移以后的结果未超出一个字节或一个字的表达范围,那么每左移一次,原操作数每一位的权增加了一倍,也即相当于原数乘2。 例如:实现把寄存器AL中的内容(设为无符号数)乘10,结果存放在AX中。 XOR AH,AH ;(AH)=0将AH清零
SHL AL,1 ;2X,设(AL)=X,并且左移一次 MOV BX,AX ;送入BX暂存2X SHL AX,1 ;4X将AX左移一次 SHL AX,1 ;8X将AX再左移一次 ADD AX,BX ;8X+2X (2)算术右移指令SAR 格式:SAR OPRD,m
该指令使操作数右移m位,同时每移一位,左边的符号位保持不变,移出的最低位进入标志位CF。 例如:MOV CL,5 SAR [DI],CL
如指令执行前:(DS)=0F800H,(DI)=180AH,(0F980A)=0064H 0000 0000 0110 0100B 0000 0000 0000 0011B
如指令执行后:(0F980A)=0003H,CF=0
对于有符号数和无符号数而言,算术右移一位相当于除以2。如果最高有效位是0,那么右移之后,在左边添加的就是0;如果最高有效位是1,那么右移之后,在左边添加的就是1。 (3)逻辑右移指令SHR 格式:SHR OPRD,m
该指令使操作数右移m位,同时每移一位,左边用0补足,移出的最低位进入标志位CF。对于无符号数而言,逻辑右移一位相当于除以2。
在汇编语言程序设计中,经常需要对以位为单位的数据进行合并和分解处理。一般通过移位指令和逻辑运算指令进行这种数据的合并和分解处理。
例如:假设DATA1和DATA2各长4位,分别存放在AL寄存器的低4位和高4位中,现要把它们分别存放到BL寄存器和BH寄存器的低4位中。 MOV BL,AL ;使(BL)=AL AND BL,0FH ;将BL与0F相与 MOV BH,AL ;使(BH)=AL
MOV CL,4 ;规定移位次数(CL)=4 SHR BH,CL ;将BH逻辑右移4位 3.循环移位指令
8086 8088有4条循环移位指令,这些指令可以一次只移一位,也可以一次移多位。如移多位,那么移位次数存放在CL寄存器中。这些指令的格式如下: