数据传送指令
MOV
1 2 3 4
| mov reg/mem, imm mov reg/mem/seg, reg mov reg/seg, mem mov reg/mem, seg
|
注:
- 当src是imm,dest是mem时,二者之一必须用ptr指定类型
- cs不能做目的操作数,ip既不能做源操作数也不能做目的操作数
- 两个操作数必须类型一致
- 立即数不能送直接寻址的内存单元
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
AH送标志指令SAHF
标志进栈指令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的余数
|
符号扩展指令
CBW
将AL
的最高有效位扩展到AH
CWD
将AX
的内容符号扩展形成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号中断