🎨 颜色标记说明

  • 粉色:特别重要、主线必掌握、优先复盘的内容。
  • 蓝色:核心概念、术语、分类名。
  • 橙色:需要关注的边界、易错点、注意事项。
  • 绿色:解释类内容、帮助理解知识点。

加法指令

ADD

1
add destination, source

ADD 执行普通加法,结果写回目标操作数,并更新 CF、OF、SF、ZF、AF、PF 等状态标志。

1
2
mov al, 0FFh
add al, 1 ; AL = 00h, CF = 1, ZF = 1

这里按无符号数解释发生进位,所以 CF = 1;按 8 位有符号数解释,-1 + 1 = 0,没有有符号溢出。

ADC

1
adc destination, source

实际计算:

1
destination = destination + source + CF

ADC 用于处理超过寄存器宽度的多精度加法。

1
2
3
; EDX:EAX + ECX:EBX
add eax, ebx
adc edx, ecx

低 32 位产生的进位通过 CF 传递给高 32 位。

INC

1
inc eax

INC 把操作数加 1。它会影响多数算术标志,但不修改 CF

因此 INC 不能替代需要传播进位的 ADD。

减法指令

SUB

1
sub destination, source

实际计算:

1
destination = destination - source

SUB 会更新 CF、OF、SF、ZF、AF、PF。减法中的 CF 可以理解为无符号借位标志。

SBB

1
sbb destination, source

实际计算:

1
destination = destination - source - CF

它与 ADC 对应,用于多精度减法:

1
2
3
; EDX:EAX - ECX:EBX
sub eax, ebx
sbb edx, ecx

DEC

DEC 把操作数减 1,与 INC 一样不会修改 CF

NEG 与补码

1
neg eax

NEG 计算 0 - EAX,也就是求二进制补码相反数:

1
按位取反 + 1
1
2
mov eax, 5
neg eax ; EAX = FFFFFFFBh,也就是 -5

若源操作数为 0,CF = 0;只要源操作数非 0,CF = 1。对最小有符号数求负会超出表示范围并置 OF

BCD 调整指令

DAADAS 用于对压缩 BCD 加减结果做十进制调整,主要依赖 AFCF

指令 用途
DAA 调整加法后的 AL
DAS 调整减法后的 AL

它们属于历史兼容指令,在 64 位模式下不可用。现代逆向中不常见,但遇到老程序、财务编码或刻意混淆时仍要能识别。

无符号乘法 MUL

单操作数 MUL 使用隐式累加器,结果宽度是操作数宽度的两倍。

操作数宽度 被乘数 结果
8 Bit AL AX
16 Bit AX DX:AX
32 Bit EAX EDX:EAX
64 Bit RAX RDX:RAX
1
2
3
mov eax, 100000h
mov ecx, 1000h
mul ecx ; EDX:EAX = EAX * ECX

如果结果高半部分非零,说明结果无法只放进低半部分,CFOF 会置 1。

有符号乘法 IMUL

IMUL 按有符号数解释操作数,常见三种形式:

1
2
3
imul ecx                ; EDX:EAX = EAX * ECX
imul eax, ecx ; EAX = EAX * ECX
imul eax, ecx, 10 ; EAX = ECX * 10

双操作数、三操作数形式只保留目标宽度的低位结果。若舍弃的高位不是低位结果的正常符号扩展,CFOF 会置 1。

除法 DIV 与 IDIV

除法也使用隐式被除数和结果寄存器:

除数宽度 被除数 余数
8 Bit AX AL AH
16 Bit DX:AX AX DX
32 Bit EDX:EAX EAX EDX
64 Bit RDX:RAX RAX RDX
1
2
3
4
xor edx, edx
mov eax, 100
mov ecx, 7
div ecx ; EAX = 14, EDX = 2

DIV 按无符号数处理;IDIV 按有符号数处理。

除法前的数据扩展

无符号除法常把高半部分清零:

1
2
xor edx, edx
div ecx

有符号除法需要把低半部分符号扩展到高半部分:

指令 扩展
CBW AL -> AX
CWD AX -> DX:AX
CDQ EAX -> EDX:EAX
CQO RAX -> RDX:RAX
1
2
3
4
mov eax, -100
cdq
mov ecx, 7
idiv ecx

除法异常

以下情况会触发除法错误异常 #DE

  • 除数为 0;
  • 商超出目标寄存器可表示范围。

除法溢出不是通过 CF 或 OF 报告,而是直接触发异常。

标志位速记

指令 关键点
ADD/SUB 正常更新算术标志
ADC/SBB 额外使用 CF 传播进位或借位
INC/DEC 不修改 CF
NEG 计算补码相反数
MUL/IMUL 关注隐式结果寄存器与 CF/OF
DIV/IDIV 关注高低寄存器、扩展与 #DE

学习检查清单

检查项 状态
能用 ADC/SBB 完成高低位进位传递 待复盘
记得 INC/DEC 不修改 CF 待复盘
能写出 MUL、DIV 的隐式寄存器组合 待复盘
能区分无符号清零与有符号 CDQ 扩展 待复盘
知道除零与商溢出会触发 #DE 待复盘