数据传送指令

MOV

1
2
3
4
mov reg/mem, imm
mov reg/mem/seg, reg
mov reg/seg, mem
mov reg/mem, seg

注:

  1. 当src是imm,dest是mem时,二者之一必须用ptr指定类型
  2. cs不能做目的操作数,ip既不能做源操作数也不能做目的操作数
  3. 两个操作数必须类型一致
  4. 立即数不能送直接寻址的内存单元
1
2
3
4
5
;错误
mov word ptr[1000h],32A8h
;修改
mov ax, 21A8h
mov [1000h], ax

XCHG

1
2
xchg reg, reg/mem
xchg reg/mem, reg

堆栈操作指令

栈顶是地址较小的一端

修改sp值的操作:

  • 子程序调用CALL
  • 子程序返回RET
  • 中断调用INT
  • 中断返回IRET

PUSH

1
push r16/m16/seg	;sp <- sp - 2, ss:[sp] <- r16/m16/seg

POP

1
pop r16/m16/seg		;r16/m16/seg <- ss:[sp], sp <- sp + 2, 

标志传送指令

标志送AH指令LAHF

1
lahf	;ah <- flags的低字节

AH送标志指令SAHF

1
sahf	;flags的低字节 <- ah

标志进栈指令PUSHF

1
pushf	;sp <- sp - 2, ss:[sp] <- flags

标志出栈指令POPF

1
popf	;flags <- ss:[sp], sp <- sp + 2

地址传送指令

LEA

1
lea r16, mem	;r16 <- mem的有效地址

LDS&LES

1
2
lds r16, mem	;r16 <- mem的有效地址, ds <- mem + 2
les r16, mem ;r16 <- mem的有效地址, es <- mem + 2

状态标志

进位标志CF是针对无符号整数运算设计的,反应无符号数据加减运算是否超出范围,是否需要利用进(借)位反映正确结果。

  • N位无符号数据加减运算结果范围是\(0\sim 2^N - 1\)

溢出标志OF用于表示有符号整数进行加减运算的结果是否超出范围

  • 处理器默认采用补码的形式表示有符号整数,N位补码表达的范围是\(-2^{N-1}\sim+2^{N-1}-1\)
标志 0 1
CF (加减)没有进位或借位 (加减)有进位或借位
OF 未超出范围 超出范围
ZF 运算结果不是0 运算结果是0
SF 最高位为0 最高位为1
PF 最低字节中"1"的个数是奇数 最低字节中"1"的个数是偶数
AF 最低半字节无进位 最低半字节有进位
  • 只有当两个相同符号数相加(含两个不同符号数相减)而运算结果的符号与原数据符号相反时产生溢出

符号值对应表:

标志 1 0
CF CY NC
OF OV NV
ZF ZR NZ
SF NG PL
PF PE PO
AF AC NA

运算指令对标志位的影响:

说明:0:清零 ✓:有影响 X:无影响 -:不确定(未定义)

加法指令

ADD

1
2
add reg, imm/reg/mem	;reg <- reg + imm/reg/mem
add mem, imm/reg ;mem <- mem + imm/reg

ADC

1
2
adc reg, imm/reg/mem	;reg <- reg + imm/reg/mem + CF
adc mem, imm/reg ;mem <- mem + imm/reg + CF

INC

不影响CF,其他影响与ADD一致

1
inc reg/mem		;reg/mem <- reg/mem + 1

减法指令

SUB

1
2
sub reg, imm/reg/mem	;reg <- reg - imm/reg/mem
sub mem, imm/reg ;mem <- mem - imm/reg

SBB

1
2
sbb reg, imm/reg/mem	;reg <- reg - imm/reg/mem - CF
sbb mem, imm/reg ;mem <- mem - imm/reg - CF

DEC

不影响CF,其他影响与SUB一致

1
dec reg/mem		;reg/mem <- reg/mem - 1

NEG

对标志位的影响和用零做减法的SUB指令一样

1
2
neg reg/mem		;reg/mem <- 0 - reg/mem
;对操作数 取反+1

CMP

对标志位的影响和sub指令一样

1
2
cmp reg, imm/reg/mem	;reg - imm/reg/mem
cmp mem, imm/reg ;mem - imm/reg

乘法指令

如果乘积的高一半(AH/DX)没有有效数值,OF=CF=0,否则OF=CF=1

MUL

1
2
3
;无符号
mul r8/m8 ;ax <- al × r8/m8
mul r16/m16 ;dx.ax <- ax × r16/m16

iMUL

1
2
3
;有符号
imul r8/m8 ;ax <- al × r8/m8
imul r16/m16;dx.ax <- ax × r16/m16

除法指令

DIV

1
2
3
4
5
;无符号
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
;有符号	余数和被除数符号相同
idiv r8/m8 ;al <- ax ÷ r8/m8的商
;ah <- ax ÷ r8/m8的余数
idiv r8/m8 ;ax <- dx.ax ÷ r16/m16的商
;dx <- dx.ax ÷ r16/m16的余数

符号扩展指令

CBWAL的最高有效位扩展到AH

CWDAX的内容符号扩展形成DX

逻辑运算指令

AND/OR/XOR/TEST

1
2
逻辑运算助记符 reg, imm/reg/mem	;reg <- reg 逻辑运算助记符 imm/reg/mem
逻辑运算助记符 mem, imm/reg ;mem <- mem 逻辑运算助记符 imm/reg

所有双操作数的逻辑指令均设置CF=OF=0

NOT

1
not reg/mem		;reg/mem <- ~reg/mem

移位指令

根据移入的位设置进位标志CF,根据移位后的结果影响SF ZF PF;当进行1位移动,根据最高符号位有变化设置OF = 1,移位超过1位,OF不确定

1
2
3
4
shl reg/mem, 1/cl	;最低位补0, 最高位进入cf
shr reg/mem, 1/cl ;最高位补0, 最低位进入cf
sal reg/mem, 1/cl ;与shl相同
sar reg/mem, 1/cl ;最高位不变, 最低位进入cf

循环移位指令

根据移入的位设置进位标志CF,不影响SF ZF PF AF,对OF与移位指令影响一致

1
2
3
4
rol reg/mem, 1/cl	;不带进位循环左移
ror reg/mem, 1/cl ;不带进位循环右移
rcl reg/mem, 1/cl ;带进位循环左移
rcr reg/mem, 1/cl ;带进位循环右移

控制转移指令

三种寻址方式:

比较无符号数的高低:

助记符 标志位 说明
JB/JNAE CF = 1 低于/不高于等于转移
JNB/JAE CF = 0 不低于/高于等于转移
JBE/JNA CF = 1或 ZF = 1 低于等于/不高于转移
JNBE/JA CF = 0 且 ZF = 0 不低于等于/高于

比较有符号数的大小:

助记符 标志位 说明
JL/JNGE SF\(\neq\)OF 小于/不大于等于转移
JNL/JGE SF = OF 不小于/大于等于转移
JLE/JNG SF\(\neq\)OF 或 ZF = 1 小于等于/不大于转移
JNLE/JG SF = OF 且 ZF = 0 不小于等于/大于转移

子程序指令

CALL

1
2
3
4
5
6
7
8
;段内调用
call label ;sp <- sp - 2, ss:[sp] <- ip, ip <- ip + 16
call r16/m16 ;sp <- sp - 2, ss:[sp] <- ip, ip <- r16/m16
;段间调用
call far ptr label ;sp <- sp - 2, ss:[sp] <- cs, sp <- sp - 2, ss:[sp] <- ip
;ip <- label的偏移地址, cs <- label的段地址
call far ptr mem ;sp <- sp - 2, ss:[sp] <- cs, sp <- sp - 2, ss[sp] <- ip
;ip <- [mem], cs <- [mem + 2]

RET

1
2
3
4
5
6
;段内返回
ret ;ip <- ss:[sp], sp <- sp + 2
ret i16 ;ip <- ss:[sp], sp <- sp + 2, sp <- sp + i16
;段间返回
ret ;ip <- ss:[sp], sp <- sp + 2, cs <- ss:[sp], sp <- sp + 2
ret i16 ;ip <- ss:[sp], sp <- sp + 2, cs <- ss:[sp], sp <- sp + i16

中断指令

外部中断

外部中断——来自CPU之外的原因引起的中断,又可以分成

  • 可屏蔽中断:可由CPU的中断允许标志IF控制
  • 非屏蔽中断:不受CPU的中断允许标志IF控制

内部中断

内部中断——CPU内部执行程序引起的中断,又可以分成:

  • 除法错中断:执行除法指令,结果溢出产生的 0 号中断
  • 指令中断:执行中断调用指令INT i8产生的 i8号中断
  • 断点中断:用于断点调试(INT 3)的 3 号中断
  • 溢出中断:执行溢出中断指令into,OF=1产生的 4 号中断
  • 单步中断:TF=1在每条指令执行后产生的 1号中断