8086指令系统之算数运算指令

本篇介绍了汇编指令中如何进行运算,包括加、减、乘、除

前置问题:

  1. 怎么做多字节的加减法?
  2. 为什么加减法指令不分有符号数和无符号数,而乘除法的有符号数和无符号数运算分别是不同的指令
  3. 如何确定指令执行的是字节操作还是字操作?
  4. 符号扩展指令再什么时候会用到,如何用?
  5. 取负指令NEG为什么执行的是取反加一?

加法指令

ADD 加法指令

指令格式:ADD 目的, 源

指令功能:目的源+目的

ADC 带进位的加法指令

ADC: Addition with Carry

指令格式:ADC 目的, 源

指令功能:目的源+目的+CF

用作多字节加法

注意:

  1. 上面两条指令的源操作数可以是寄存器、存储器或者立即数
  2. 目的操作数只能用寄存器和存储单元
  3. 源和目的操作数不能同时为存储器,而且他们的类型必须一致,同时为字节或者字
  4. 它们影响到的标志位:CF、OF、PF、SF、ZF、AF

INC 增量指令

INC: Increment

指令格式:INC 目的

指令功能:目的目的+1

注意:

  1. 目的操作数可以是通用寄存器或内存。指令执行后影响AF、OF、PF、SF和ZF,但是进位标志CF不受影响
  2. 指令中只有一个操作数,如果是内存单元,则要用PTR操作符说明是字节还是字

减法指令

SUB减法指令

指令格式:SUB 目的, 源

指令功能: 目的目的 - 源

SBB 带借位的减法指令

指令格式: SBB 目的, 源

指令功能:目的目的 - 源 - CF

SBB主要用于多字节减法中

DEC 减量指令

DEC: Decrement

指令功能:DEC 目的

指令功能:目的目的 - 1

NEG 取负指令

指令格式:NEG 目的

指令功能:目的$$0 - 目的(取反加一)

CMP 比较指令

CMP: Compare

指令格式:CMP 目的, 源

指令功能:目的 - 源

实际上是做减法,但是结果不送到目的,只改变标志位

(一般紧跟条件转移指令实现跳转)

乘法指令

MUL 无符号数乘法指令

指令格式: MUL 源

指令功能:把源操作数和累加器(Accumulater)中的数,都当成无符号数,然后将两数相乘

注意:

  1. 其中有一个操作数一定是累加器
  2. **如果源操作数是一个字节,那么AXAX*源**
  3. **如果源操作数是一个字,那么(DX,AX)AX*源**
  4. 源操作数可以是寄存器或存储单元,不能是立即数
  5. 源操作数是存储单元时,应使用PTR说明是字节还是字
  6. MUL指令执行后影响CF和OF标志
  7. 如果结果的高半部分不为0,则CF、OF均置1。否则CF、OF清零
  8. 通过测试这两个标志,可以检测并去除结果中的无效前导零

IMUL 有符号数乘法指令

指令格式:IMUL 源

指令功能:把源操作数和累加器中的数,都作为带符号数进行相乘

存放结果的方式与MUL相同,最后给乘积赋予正确的符号

指令结束后,如果乘积的高半部分不是全0或者全1,则置CF=1,OF=1.若结果高半部分为全0或者全1,则使CF=0,OF=0. 这样来决定是否需要保存积的高半部分

为什么有MUL和IMUL?

指令不知道是有符号数还是无符号数,需要程序员赋予其意义

除法指令

DIV 无符号数除法指令

指令格式: DIV 源

指令功能:对两个无符号二进制数进行除法操作。

如果源操作数是字节,被除数必须放在AX中,并且:

  1. ALAX/源(字节)的商
  2. AHAX/源(字节)的余数
  3. 要是被除数只有8位,必须将其放在AL中,并将AH清零,然后相除

如果源操作数是字,被除数必须放在DX和AX中,并且:

  1. AX(DX,AX)/源(字)的商
  2. DX(DX,AX)/源(字)的余数

要是被除数只有16位,除数也是16位,则必须将16位被除数送入AX中,再将DX清零,然后相除、

与被除数和除数一样,商和余数都是无符号数

IDIV 有符号数除法指令

指令格式:IDIV 源

指令功能:功能与DIV相同,但操作数都必须是带符号数,商和余数也是带符号数,而且规定余数的符号和被除数的符号相同

进行除法时,如果商超过了目标寄存器AL或AX所能存放的数的范围,计算机会自动产生除法错中断,相当于执行了除数为0的运算,得到的商和余数都不确定

对于带符号数的除法指令,字节操作时要求被除数为16位,字操作时要求被除数为32位,如果不能满足这个条件时,不能简单将高位置0/1,而应应该用符号扩展指令,再执行除法指令

CBW 把字节转换为字指令

CBW: Convert Byte to Word

指令格式:CBW

指令功能:把AL中的字节的符号位扩充到AH的所有位,这是AH被称为是AL的符号扩充

CBW不影响标志位

CWD 把字转换为双字指令

CWD: Convert Word to Double Word

指令格式:CWD

指令功能:把AX中字的符号位扩充到DX寄存器的所有位中去