0%

8086指令基础 - 算术运算类指令

最近在学习 16位汇编编程,所以顺便将每日所学记录下来,一方面为了巩固学习的知识,另一方面也为同样在学习汇编开发的童鞋们提供一份参考。

运行环境:

  • 操作系统: Windows 10家庭版
  • 编译器:Windows XP Debug

算术运算类指令

掌握:ADD/ADC/INC、SUB/SBB/DEC/ NEG/CMP
熟悉:MUL/IMUL、DIV/IDIV
理解:CBW/CWD、DAA/DAS、 AAA/ AAS/AAM/AAD

加法指令ADD

1
2
3
4
ADD reg,imm/reg/mem
;reg←reg+imm/reg/mem
ADD mem,imm/reg
;mem←mem+imm/reg

带进位加法指令ADC

ADC指令将源与目的操作数相加,再加上进位CF标志,
结果送到目的操作数 ADC指令按状态标志的定义相应设置
ADC指令主要与ADD配合,实现多精度加法运算

1
2
3
4
ADC reg,imm/reg/mem
;reg←reg+imm/reg/mem+CF
ADC mem,imm/reg
;mem←mem+imm/reg+CF

增量指令INC(increment)

INC指令对操作数加1(增量)INC指令不影响进位CF标志,按定义设置其他状态标志

1
2
INC reg/mem
;reg/mem←reg/mem+1

减法指令SUB(subtract)

  • SUB指令将目的操作数减去源操作数,结果送到目的操作数
    SUB指令按照定义相应设置状态标志
1
2
3
4
SUB reg,imm/reg/mem
;reg←reg-imm/reg/mem
SUB mem,imm/reg
;mem←mem-imm/reg

带借位减法指令SBB

SBB指令将目的操作数减去源操作数,再减去借位CF(进位),结果送到目的操作数。
SBB指令按照定义相应设置状态标志
SBB指令主要与SUB配合,实现多精度减法运算

1
2
3
4
SBB reg,imm/reg/mem
;reg←(reg-(imm/reg/mem)-CF)
SBB mem,imm/reg
;mem←mem-imm/reg-CF

demo:

1
2
3
4
5
6
7
mov ax,4652h    ;ax=4652h
sub ax,0f0f0h ;ax=5562h,CF=1
mov dx,0234h ;dx=0234h
sbb dx,0f0f0h ;dx=1143h,CF=1
;DX.AX=0234 4652H
-F0F0 F0F0H
=1143 5562H

减量指令DEC(decrement)

DEC指令对操作数减1(减量)
DEC指令不影响进位CF标志,按定义设置其他状态标志

1
2
DEC reg/mem
;reg/mem←reg/mem-1

INC指令和DEC指令都是单操作数指令主要用于对计数器和地址指针的调整

求补指令NEG(negative)

NEG指令对操作数执行求补运算:用零减去操作数,然后结果返回操作数
求补运算也可以表达成:将操作数按位取反后加1
NEG指令对标志的影响与用零作减法的SUB指令一样

1
2
NEG reg/mem
;reg/mem←0-reg/mem

比较指令CMP(compare)

CMP指令将目的操作数减去源操作数,按照定义相应设置状态标志
CMP指令执行的功能与SUB指令相同,但结果不回送目的操作数

1
2
3
4
CMP reg,imm/reg/mem
;reg-imm/reg/mem
CMP mem,imm/reg
;mem-imm/reg

乘法指令

不带符号位乘法(MUL)

1
2
3
4
5
6
MUL r8/m8
;无符号字节乘法
;AX←AL×r8/m8
MUL r16/m16
;无符号字乘法
;DX.AX←AX×r16/m16

带符号位的乘法(IMUL)

1
2
3
4
5
6
IMUL r8/m8
;有符号字节乘法
;AX←AL×r8/m8
IMUL r16/m16
;有符号字乘法
;DX.AX←AX×r16/m16

MUL指令——若乘积的高一半(AH或DX)为0,则OF=CF=0;否则OF=CF=1
IMUL指令——若乘积的高一半是低一半的符号扩展,则OF=CF=0;否则均为1

除法指令

不带符号位的除法(DIV)

1
2
3
4
5
6
DIV r8/m8   
;无符号字节除法:
AL←AX÷r8/m8的商,Ah←AX÷r8/m8的余数
DIV r16/m16
;无符号字除法:
;AX←DX.AX÷r16/m16的商,DX←DX.AX÷r16/m16的余数

带符号位的除法(IDIV)

1
2
3
4
5
6
DIV r8/m8   
;有符号字节除法:
AL←AX÷r8/m8的商,Ah←AX÷r8/m8的余数
IDIV r16/m16
;有符号字除法:
;AX←DX.AX÷r16/m16的商,DX←DX.AX÷r16/m16的余数
  • 除法指令分无符号和有符号除法指令
  • 除法指令的除数显式给出,隐含使用另一个操作数AX和DX作为被除数字节量除法:AX除以r8/m8,8位商存入AL,8位余数存入AH字量除法:DX.AX除以r16/m16,16位商存入AX,16位余数存入DX
  • 除法指令对标志没有定义
  • 除法指令会产生结果溢出

位移指令

左移指令(SHL)

使目的操作数逻辑左移一位,最低位用 0 填充。最高位移入进位标志位,而进位标志位中原来的数值被丢弃

若将 1100 1111 左移 1 位,该数就变为 1001 1110:

1
2
3
4
SHL reg, imm8
SHL mem, imm8
SHL reg, CL
SHL mem, CL

位元乘法

数值进行左移(向 MSB 移动)即执行了位元乘法(Bitwise Multiplication)

1
2
mov dl, 5            ; 移动前:00000101 = 5
shl dl, 1 ; 移动后:00001010 = 10

右移指令(SHR)

使目的操作数逻辑右移一位,最高位用 0 填充。最低位复制到进位标志位,而进位标志位中原来的数值被丢弃

1
2
3
4
mov al, 0D0h     ; AL = 11010000b
shr al, 1 ; AL = 01101000b, CF = 0
mov al, 00000010b
shr al, 2 ; AL = 00000000b, CF = 1

位元除法

数值进行右移(向 LSB 移动)即执行了位元除法(Bitwise Division)。

1
2
3
4
mov dl, 32           ;移动前:00100000 = 32
shr dl, 1 ;移动后:00010000 = 16
mov al, 01000000b ;AL = 64
shr al, 3 ;除以 8, AL = 00001000b