8086/8088指令系统详解之(2)算术运算指令

时间:2023-01-01 00:43:51

一,算术运算的数据类型

8086/8088指令系统详解之(2)算术运算指令

二,算术运算指令对标志位的影响

8086/8088指令系统详解之(2)算术运算指令

8086/8088指令系统详解之(2)算术运算指令

8086/8088指令系统详解之(2)算术运算指令

8086/8088指令系统详解之(2)算术运算指令

三,二进制运算指令

1,加法指令

1)不带进位加法指令ADD(ADDition)

格式:ADD DST,SRC

操作:
将目的操作数和与源操作数相加,将结果送给目的操作数//DST <= DST+SRC

寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算

对状态位的影响:
全部影响

b,带进位加法指令ADC(ADdiion with Carry)

格式:ADC DST,SRC

操作:将目的操作数和与源操作数相加,再加上进位标志CF,将结果送给目的操作数 //DST <= DST+SRC+CF

寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算

对状态位的影响:
全部影响

c,加1指令(INCrement by 1)

格式:INC DST

操作:将目的操作数加1,结果送回目的操作数 //DST <= DST +1

寻址方式:
DST可以是MEM/REG
不可以是data/SEG

对状态位的影响:
除了CF,其他全部影响

例, 计算两个多字节十六进制数之和:3B74AC60F8H+20D59E36C1H=?

式中被加数和加数均有5个字节,可以编一个循环程序实现以上运算。假设已将被加数和加数分别存入从DATA1和DATA2开始的两个内存区,且均为低位字节在前,高位字节在后,如图4.15所示。要求相加所得结果仍存回以DATA1为首址的内存区。

程序流程图如下图,程序如下:

        MOV     CX,5                ;设置循环次数
        MOV     SI,0                ;置位移量初值
        CLC                          ;清进位CF
LOOPER:MOV      AL,DATA2[SI]       ;取一个加数
        ADC      DATA1[SI],AL       ;和一个被加数相加
        INC      SI                  ;位移量加1
        DEC      CX                  ;循环次数减1 
        JNZ      LOOPER    ;加完否,若没完,转LOOPER,继续相加
        HLT                          ;程序暂停 

8086/8088指令系统详解之(2)算术运算指令

8086/8088指令系统详解之(2)算术运算指令

2)减法指令

a,不带进位减法指令SUB(subtract)

格式:SUB DST,SRC

操作:
将目的操作数减去源操作数,结果送回目的操作数 //DST <= DST-SRC

寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算

对状态位的影响:
全部影响

b,带进位减法指令SBB(subtract with borrow)

格式:SBB DST,SRC

操作:将目的操作数减去源操作数,再减去标志位CF,结果送回目的操作数
//DST <= DST-SRC-CF

寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算

对状态位的影响:
全部影响

c,减1指令DEC(Decrement)

格式:DEC DST
操作: 将目的操作数减1,结果送回目的操作数 //DST <= DST -1

寻址方式:
DST可以是MEM/REG
不可以是data/SEG

对状态位的影响:
除了CF,其他全部影响

d,求补指令NEG(Negate)

格式:NEG DST

操作:将0减去目的操作数,结果送给目的操作数 // DST <= 0-DST

寻址方式:
DST可以是MEM/REG

对状态位的影响:
全部影响

注:利用NEG指令可以得到负数的绝对值

e,比较指令CMP(Compare)

格式:CMP DST,SRC

操作:目的操作数减去源操作数,结果并不送到目的操作数中,因此,执行后,二者内容均保持不变,结果反映在状态标志位上 //DST-SRC

寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算

对状态位的影响:
相当于减法,但不保存结果,仅影响标志。

例1:
内存数据段存放了200个带符号数,首地址为TAB1,要求将各数取绝对值后存入以TAB2为首址的内存区。

由于200个带符号数中可能既有正数,又有负数,因此先要判断正负。如为正数,可以原封不动地传送到另一内存区;如为负数,则需先求补即可得到负数的绝对值,然后再传送。程序如下:

          LEA   SI,TAB1       ;(SI)←源地址指针
          LEA   DI,TAB2       ;(DI)←目标地址指针
          MOV   CX,200        ;(CX)←循环次数 
CHECK:   MOV   AL,[SI]       ;取一个带符号数到AL
          OR    AL,AL         ;AL内容不变,只影响标志位
          JNS   NEXT           ;若(SF)=0,则转NEXT
          NEG   AL             ;否则求补
 NEXT:   MOV   [DI],AL       ;传送到目标地址
          INC   SI             ;源地址加1
          INC   DI             ;目标地址加1
          DEC   CX             ;循环次数减1
          JNZ   CHECK          ;如不等于零,则转CHECK
          HLT                  ;停止 

例2:
在数据段从myoata开始的存储单元中分别存放两个8位无符号数,试比较他们的大小,并将大者传送到max单元。

       LEA  BX ,MYDATA       ;MYDATA偏移地址送BX
       MOV  AL ,[BX]         ;第一个无符号数送AL  
       INC  BX               ;BX指向第二个无符号数 
       CMP  AL,[BX]          ;两个数比较
       JNC  DONE             ;若CF=0,则转DONE
       MOV  AL ,[BX]         ;否则,第二个无符号数送AL
DONE   MOV  MAX ,AL          ;较大的无符号数送MAX单元
       HLT                   ;停止
3)乘法指令

乘法指令具有两个操作数,一个是源操作数,另一个目的操作数是隐含的操作数。

a,无符号乘法指令MUL(Unsigned Multiple)

格式:MUL SRC

操作:两个操作数均按无符号数来处理。
当SRC为8位时,隐含的目的操作数从AL中获得,乘积为16位,放在AX中。
当SRC为16位时,隐含的目的操作数从AX中获得,乘积为32位,放在DX:AX中。

8086/8088指令系统详解之(2)算术运算指令

例:

   MUL AL               ;AL乘AL,结果放在AX中
   MUL BX               ;AX乘BX,结果在DX:AX中
   MUL BYTE PTR[DI+6]   ;AL乘存储器(8位),结果放在AX中
   MUL WORD PTR ALPHA   ;AX乘存储器(16位)结果放在DX:AX中

寻址方式:SRC可以是REG/MEM
对状态位的影响:MUL指令对CF和OF有影响,SF,ZF,AF和PF不确定。

如果运算结果的高半部分(AH或DX中)为0,则(CF)=(DF)=0,若(CF)=(DF)=1,则说明AH或DX中包含着乘积的有效数字。
例:

      MOV AL, 14H      ;(AL)=14H
      MOV CL, 05H      ;(CL)=05H
      MUL CL           ;(AX)=0064H, (CF)=(OF)=0

本例中的高半部分AH为0,因此(CF)=(DF)=0。

b,带符号数的乘法指令IMUL(Signed Multiple)

格式:IMUL SRC

操作:两个操作数均按有符号数来处理。
当SRC为8位时,隐含的目的操作数从AL中获得,乘积为16位,放在AX中。
当SRC为16位时,隐含的目的操作数从AX中获得,乘积为32位,放在DX:AX中。

寻址方式:SRC可以是REG/MEM

对状态位的影响:MUL指令对CF和OF有影响,SF,ZF,AF和PF不确定。

若乘积的高半部分仅仅是低半部分符号位的扩展,则状态标志位(CF)=(DF)=0,若(CF)=(DF)=1,说明高半部分包含有效数字。

4)除法指令

a,无符号数除法指令DIV(Unsigned divide)

格式:DIV SRC
操作:
1、字节除法:AX/SRC, 商=>AL, 余数=>AH
2、字除法:DX,AX/SRC, 商=>AX, 余数=>DX
 
8086/8088指令系统详解之(2)算术运算指令

b,带符号数除法指令IDIV(Signed divide)

格式:IDIV SRC
操作:类似DIV。

说明:
1、SRC 为 REG/MEM。
2、除法指令影响状态标志但对所有标志无定义。
3、商可能出现溢出,会立即产生除法溢出中断。
 
5)符号扩展指令

a,字节扩展指令

CBW(Convert byte to word)字节扩展到字
格式:CBW ;如果(AL)<80H,则(AH)00H,否则(AH)0FFH
操作:把AL扩展到AX。

b,字扩展指令

CWD(Convert word to double word)字扩展到双字
格式:CWD ;如果(AX)<8000H,则(DX)0000H,否则(DX)0FFFFH
操作:把AX扩展到DX,AX 。

说明:
1、CBW和CWD对标志位无影响
2、扩展方法
由符号扩展指令实现,正数补0,负数补1。
(无符号数的扩展:将高位补0)

例:若(AL)=0F2H,执行 CBW 后,(AX)=0FFF2H

4,十进制数(BCD码)运算指令

在微处理器中,没有专用的BCD码运算指令,使用二进制运算指令进行BCD码数的运算后,要用BCD码运算调整指令进行调整,重新得到BCD码的结果。举例如下:
1、34H+29H 按照二进制加法得到的结果是 5DH
2、用调整指令DAA调整成BCD码,规则是

  • 低4位>9或AF=1结果加06H;
  • 高4位>9或CF=1结果加60H;

3、调整以后得到:5DH + 06H = 63H,这是BCD码运算的结果。

压缩型BCD码的调整指令:

DAA加法调整
DAS减法调整

非压缩格型BCD码的调整指令:

AAA加法调整
AAS减法调整
AAM乘法调整
AAD除法调整

这类指令的操作数隐含为AL或AX

AAA指令的操作为:

如果  (AL) ∧0FH>9 或 (AF)=1
则       (AL) ←(AL)+06H      
        (AH) ←(AH)+1
        (AF) ← 1
        (CF) ←(AF)
        (AL) ←((AL) ∧ 0FH)
否则  (AL) ←((AL) ∧ 0FH)

DAA指令的操作为:

如果  (AL) ∧0FH>9, (AF)=1
则       (AL) ←(AL)+06H      
        (AF) ← 1
如果  (AL) > 9FH 或 (CF)=1
则       (AL) ←(AL)+60H      
        (CF) ← 1

例]要求计算两个十进制数之和,7+8=?。可用以下指令实现:

MOV  AX,  0007H     ;(AL)=07H,(AH)=00H
MOV  BL,  08H       ;(BL)=08H
ADD  AL,  BL        ;(AL)=0FH
AAA                 ;(AL)=05H,(AH)=01H
                    ;(CF)=(AF)=1

MOV  AX,  0007H     ;(AL)=07H,(AH)=00H
MOV  BL,  08H       ;(BL)=08H
ADD  AL,  BL        ;(AL)=0FH
DAA                 ;(AL)=15H,(AH)=00H 
                    ;(CF)=0,(AF)=1

AAS指令的操作为: (非压缩型BCD码调整)

如果  (AL) ∧0FH>9 或 (AF)=1
则       (AL) ←(AL)-06H      
        (AH) ←(AH)-1
        (AF) ← 1
        (CF) ←(AF)
        (AL) ←((AL) ∧ 0FH)
否则  (AL) ←((AL) ∧ 0FH)

DAS指令的操作为: (压缩型BCD码调整)

如果  (AL) ∧0FH>9, (AF)=1
则       (AL) ←(AL)-06H      
        (AF) ← 1
如果  (AL) > 9FH 或 (CF)=1
则       (AL) ←(AL)-60H      
        (CF) ← 1

AAM指令的操作为:(将二进制数转换成十进制数)

(AH)←(AL)/0AH的商;即AL除以10,商送AH
(AL)←(AL)/0AH的余数;即AL除以10,余数送AL

例:要求进行以下十进制乘法运算:7*9=?

解:可编程序段如下

MOV  AL,07H    ;(AL)=07H
MOV  BL,09H    ;(BL)=09H
MUL  BL         ;(AX)=07H09H=003FH
AAM             ;(AH)=06H,(AL)=03H 

AAD指令的操作为:(将十进制数转换成二进制数)

    (AL)←(AH)0AH+(AL)
    (AH)←0 

例:要进行以下十进制除法运算:73÷2=?

解:可编程序段如下:

   MOV AH,07H   ;(AH)=07H,(AL)=03H
   MOV AL,03H   ;(AH)=07H,(AL)=03H
   MOV BL,02H   ;(BL)=02H
   AAD           ;(AL)=49H(即十进制数73)
   DIV BL        ;(AL)=24H(商),(AH)=01H(余数)
   AAM           ;(AH)=03H,(AL)=06H