汇编语言常用指令速查手册
0. 寄存器速查
0.1 通用寄存器(x86/x64)
数据寄存器
| 64位 | 32位 | 16位 | 8位高 | 8位低 | 主要用途 | 助记 |
|---|---|---|---|---|---|---|
| RAX | EAX | AX | AH | AL | 累加器(算术运算、I/O) | Accumulator |
| RBX | EBX | BX | BH | BL | 基址(内存寻址) | Base |
| RCX | ECX | CX | CH | CL | 计数器(循环、移位) | Counter |
| RDX | EDX | DX | DH | DL | 数据(乘除法扩展) | Data |
记忆技巧:ABCD - All Boys Count Data
示例:寄存器重叠关系
MOV EAX, 12345678H ; EAX = 12345678H
MOV AX, 1234H ; EAX = 12341234H(修改低16位)
MOV AL, 56H ; EAX = 12341256H(修改低8位)
MOV AH, 78H ; EAX = 12347856H(修改8-15位)
指针和索引寄存器
| 64位 | 32位 | 16位 | 主要用途 | 助记 |
|---|---|---|---|---|
| RSP | ESP | SP | 栈指针(指向栈顶) | Stack Pointer |
| RBP | EBP | BP | 基址指针(栈帧基址) | Base Pointer |
| RSI | ESI | SI | 源索引(字符串源地址) | Source Index |
| RDI | EDI | DI | 目的索引(字符串目标) | Destination Index |
记忆技巧:
- SP - Stack Pointer(永远指向栈顶,PUSH/POP 自动修改)
- BP - Base Pointer(常用于访问函数参数和局部变量)
- SI/DI - Source/Destination(字符串操作的黄金搭档)
示例:栈帧访问
PUSH EBP ; 保存旧的基址指针
MOV EBP, ESP ; 建立新栈帧
SUB ESP, 16 ; 分配 16 字节局部变量
MOV [EBP-4], EAX ; 访问局部变量
MOV EAX, [EBP+8] ; 访问第一个参数
x64 扩展寄存器(仅 64 位模式)
| 寄存器 | 用途 |
|---|---|
| R8 ~ R15 | 通用寄存器(64 位) |
| R8D ~ R15D | 32 位部分 |
| R8W ~ R15W | 16 位部分 |
| R8B ~ R15B | 8 位部分 |
0.2 段寄存器
| 寄存器 | 全称 | 用途 | 默认搭配 |
|---|---|---|---|
| CS | Code Segment | 代码段(指令存储) | IP/EIP/RIP |
| DS | Data Segment | 数据段(数据存储) | BX, SI, DI |
| SS | Stack Segment | 栈段(栈操作) | SP, BP |
| ES | Extra Segment | 附加段(字符串目标) | DI |
| FS | - | 附加段(线程本地存储) | - |
| GS | - | 附加段(操作系统数据) | - |
记忆技巧:CS DS SS ES - Code Data Stack Extra
示例:段寄存器覆盖
MOV AX, [BX] ; 默认 DS:[BX]
MOV AX, ES:[BX] ; 覆盖为 ES:[BX]
MOV AX, [BP] ; 默认 SS:[BP]
0.3 指令指针寄存器
| 模式 | 寄存器 | 位宽 | 说明 |
|---|---|---|---|
| 实模式/保护模式 | IP | 16位 | 指向下一条指令 |
| 保护模式 | EIP | 32位 | 扩展指令指针 |
| 长模式(x64) | RIP | 64位 | 64位指令指针 |
特点:
- ✅ 不能直接修改(通过 JMP/CALL 间接修改)
- ✅ 相对寻址基础(RIP-relative addressing)
0.4 标志寄存器(FLAGS/EFLAGS/RFLAGS)
状态标志位(反映运算结果)
| 位 | 标志 | 全称 | 含义 | 示例 |
|---|---|---|---|---|
| 0 | CF | Carry Flag | 进位/借位 | 255 + 1 → CF=1 |
| 2 | PF | Parity Flag | 奇偶(1 的个数) | 偶数个 1 → PF=1 |
| 4 | AF | Auxiliary Carry | 辅助进位(BCD) | 低 4 位进位 |
| 6 | ZF | Zero Flag | 结果为零 | 5 - 5 → ZF=1 |
| 7 | SF | Sign Flag | 符号位 | 负数 → SF=1 |
| 11 | OF | Overflow Flag | 溢出(有符号) | 127 + 1 → OF=1 |
控制标志位
| 位 | 标志 | 全称 | 含义 |
|---|---|---|---|
| 8 | TF | Trap Flag | 单步调试 |
| 9 | IF | Interrupt Flag | 中断允许 |
| 10 | DF | Direction Flag | 字符串方向(0=递增,1=递减) |
记忆技巧(状态标志):Careless Programmers Always Zero Some Operations
- CF PF AF ZF SF OF
示例:标志位应用
; 判断无符号溢出
ADD AL, BL
JC OVERFLOW ; CF=1 时跳转
; 判断有符号溢出
ADD AL, BL
JO OVERFLOW ; OF=1 时跳转
; 判断结果为零
CMP AX, BX
JZ EQUAL ; ZF=1 时跳转
; 设置方向标志
CLD ; DF=0(递增)
STD ; DF=1(递减)
0.5 寄存器使用约定(调用惯例)
Caller-Saved(调用者保存)
调用函数前需自行保存,函数可能修改:
- EAX/RAX - 返回值
- ECX/RCX - 第 4 个参数(x64)
- EDX/RDX - 第 3 个参数(x64)
Callee-Saved(被调用者保存)
函数必须保证调用前后值不变:
- EBX/RBX - 基址寄存器
- ESI/RSI - 源索引
- EDI/RDI - 目的索引
- EBP/RBP - 基址指针
- ESP/RSP - 栈指针(特殊)
x64 Windows 调用约定(前 4 个参数)
; RCX, RDX, R8, R9 传参
MOV RCX, ARG1 ; 第 1 个参数
MOV RDX, ARG2 ; 第 2 个参数
MOV R8, ARG3 ; 第 3 个参数
MOV R9, ARG4 ; 第 4 个参数
CALL FUNCTION
; RAX 存放返回值
x64 Linux 调用约定(System V AMD64 ABI)
; RDI, RSI, RDX, RCX, R8, R9 传参
MOV RDI, ARG1 ; 第 1 个参数
MOV RSI, ARG2 ; 第 2 个参数
CALL FUNCTION
0.6 特殊用途寄存器快速查找
| 操作 | 常用寄存器 | 原因 |
|---|---|---|
| 乘法/除法 | AX, DX | MUL/DIV 隐式使用 DX:AX |
| 循环计数 | CX | LOOP 指令自动递减 |
| 移位计数 | CL | SHL/SAR 可变移位量 |
| 字符串操作 | SI, DI | MOVS/CMPS 等自动修改 |
| I/O 端口 | DX | IN/OUT 间接端口寻址 |
| 栈操作 | SP | PUSH/POP/CALL/RET |
| 函数返回值 | AX/EAX/RAX | 调用约定 |
1. 数据传送指令
1.1 基本传送
MOV dest, src
- 功能:将源操作数复制到目标操作数
- 特点:不影响标志位
- 限制:不能直接内存到内存
MOV AX, BX ; 寄存器到寄存器
MOV AX, [1000H] ; 内存到寄存器
MOV [1000H], AX ; 寄存器到内存
MOV AX, 1234H ; 立即数到寄存器
XCHG op1, op2
- 功能:交换两个操作数的值
- 特点:原子操作(带 LOCK 前缀时)
XCHG AX, BX ; 交换两个寄存器
XCHG AX, [SI] ; 交换寄存器和内存
1.2 地址传送
LEA dest, src ⚠️ 易混淆
- 功能:加载有效地址(Load Effective Address)
- 关键:不访问内存,只计算地址
- 用途:地址计算、快速乘法
LEA AX, [BX+SI+10] ; AX = BX + SI + 10(地址值)
MOV AX, [BX+SI+10] ; AX = 内存[BX+SI+10]的内容
对比:MOV vs LEA
MOV AX, OFFSET VAR ; AX = VAR 的地址(编译时常量)
LEA AX, [VAR] ; AX = VAR 的地址(运行时计算)
LEA AX, [BX+SI*4+8] ; 复杂地址计算(MOV 不支持)
1.3 扩展传送
MOVSX dest, src / MOVZX dest, src
- MOVSX:符号扩展传送(保留符号)
- MOVZX:零扩展传送(高位填 0)
; AL = FFH (-1 的补码)
MOVSX AX, AL ; AX = FFFFH (-1 扩展)
MOVZX AX, AL ; AX = 00FFH (255 扩展)
2. 算术运算指令
2.1 加减运算
ADD dest, src / SUB dest, src
- 影响标志位:CF, ZF, SF, OF, PF, AF
ADD AX, BX ; AX = AX + BX
SUB AX, 10 ; AX = AX - 10
INC op / DEC op
- 特点:不影响 CF 标志位(其他同 ADD/SUB)
- 速度:通常比 ADD/SUB 1 快
INC AX ; AX = AX + 1
DEC BYTE PTR [SI] ; 内存字节 -1
ADC dest, src / SBB dest, src
- ADC:带进位加法(dest = dest + src + CF)
- SBB:带借位减法(dest = dest - src - CF)
- 用途:多精度运算
; 64 位加法示例(16 位环境)
ADD AX, CX ; 低 16 位相加
ADC BX, DX ; 高 16 位相加 + 进位
2.2 乘法运算 ⚠️ 易混淆
MUL src - 无符号乘法
- 格式:
- 8 位:
AX = AL * src - 16 位:
DX:AX = AX * src - 32 位:
EDX:EAX = EAX * src
- 8 位:
- 标志位:仅影响 CF 和 OF
- CF=OF=0:结果高半部分为 0
- CF=OF=1:结果高半部分非 0
MOV AL, 10
MUL BL ; AX = AL * BL(无符号)
IMUL - 有符号乘法(三种格式)
格式 1:单操作数(同 MUL)
IMUL BL ; AX = AL * BL(有符号)
格式 2:双操作数
IMUL AX, BX ; AX = AX * BX(有符号)
IMUL AX, 10 ; AX = AX * 10
格式 3:三操作数
IMUL AX, BX, 10 ; AX = BX * 10
对比:MUL vs IMUL
MOV AL, -2 ; AL = FEH
MOV BL, 3 ; BL = 03H
MUL BL ; AX = 254 * 3 = 762 (02FAH)
IMUL BL ; AX = -2 * 3 = -6 (FFFAH)
2.3 除法运算 ⚠️ 易混淆
DIV src - 无符号除法
- 格式:
- 8 位:
AL = AX / src,AH = AX % src - 16 位:
AX = DX:AX / src,DX = 余数 - 32 位:
EAX = EDX:EAX / src,EDX = 余数
- 8 位:
- 异常:除数为 0 或商溢出触发中断 0
MOV AX, 100
MOV BL, 3
DIV BL ; AL = 33, AH = 1
IDIV src - 有符号除法
- 格式同 DIV,但按有符号数计算
- 注意:除法前需正确扩展被除数
; 16位有符号除法
MOV AX, -100 ; AX = FF9CH
CWD ; DX:AX = FFFF:FF9CH(符号扩展)
IDIV BX ; AX = DX:AX / BX
对比:DIV vs IDIV
MOV AX, -10 ; AX = FFF6H
MOV BL, 3
DIV BL ; AL = (65526 / 3) = 85 (溢出或错误)
IDIV BL ; AL = (-10 / 3) = -3, AH = -1
2.4 符号扩展
CBW / CWD / CDQ
- CBW:AL → AX(字节扩展到字)
- CWD:AX → DX:AX(字扩展到双字)
- CDQ:EAX → EDX:EAX(双字扩展到四字)
MOV AL, -10 ; AL = F6H
CBW ; AX = FFF6H(符号位扩展)
MOV AX, -100
CWD ; DX = FFFFH, AX = FF9CH
3. 逻辑运算与移位指令
3.1 逻辑运算
AND dest, src / OR dest, src / XOR dest, src
- AND:按位与(常用于清零位、测试位)
- OR:按位或(常用于置位)
- XOR:按位异或(常用于取反、快速清零)
- 影响标志位:ZF, SF, PF;清零 CF 和 OF
AND AL, 0FH ; 清除高 4 位
OR AL, 80H ; 设置最高位
XOR AX, AX ; 快速清零(比 MOV AX, 0 快)
TEST AL, 01H ; 测试最低位(不改变 AL)
NOT op
- 功能:按位取反(一元运算)
- 特点:不影响任何标志位
NOT AL ; AL = ~AL
3.2 移位指令
逻辑移位
SHL AX, 1 ; 逻辑左移(末位补 0)
SHR AX, CL ; 逻辑右移(最高位补 0)
算术移位
SAL AX, 1 ; 算术左移(同 SHL)
SAR AX, CL ; 算术右移(保持符号位)
循环移位
ROL AX, 1 ; 循环左移(最高位 → 最低位)
ROR AX, CL ; 循环右移
RCL AX, 1 ; 带进位循环左移(含 CF)
RCR AX, CL ; 带进位循环右移
对比:SHR vs SAR
MOV AL, -8 ; AL = F8H (11111000B)
SHR AL, 1 ; AL = 7CH (01111100B = 124)
; 逻辑右移,高位补 0
MOV AL, -8 ; AL = F8H
SAR AL, 1 ; AL = FCH (11111100B = -4)
; 算术右移,保持符号位
4. 控制转移指令
4.1 无条件转移
JMP target
- 段内短转移:
JMP SHORT target(-128 ~ +127 字节) - 段内近转移:
JMP NEAR PTR target(同段内) - 段间远转移:
JMP FAR PTR target(跨段)
JMP LABEL1 ; 直接跳转
JMP BX ; 间接跳转(寄存器)
JMP [BX] ; 间接跳转(内存)
4.2 条件转移 ⚠️ 易混淆
无符号数比较跳转(基于 CMP)
CMP AX, BX ; 比较 AX 和 BX
JA target ; Jump if Above(AX > BX,无符号)
JAE target ; Jump if Above or Equal(AX >= BX)
JB target ; Jump if Below(AX < BX)
JBE target ; Jump if Below or Equal(AX <= BX)
有符号数比较跳转
CMP AX, BX
JG target ; Jump if Greater(AX > BX,有符号)
JGE target ; Jump if Greater or Equal(AX >= BX)
JL target ; Jump if Less(AX < BX)
JLE target ; Jump if Less or Equal(AX <= BX)
单标志位测试跳转
JZ target ; Jump if Zero(ZF = 1)
JNZ target ; Jump if Not Zero(ZF = 0)
JC target ; Jump if Carry(CF = 1)
JNC target ; Jump if Not Carry(CF = 0)
JS target ; Jump if Sign(SF = 1,负数)
JNS target ; Jump if Not Sign(SF = 0,正数)
JO target ; Jump if Overflow(OF = 1)
JNO target ; Jump if Not Overflow(OF = 0)
对比:无符号 vs 有符号跳转
; 设 AL = FFH, BL = 01H
CMP AL, BL
JA LABEL1 ; 会跳转(255 > 1,无符号)
JG LABEL2 ; 不跳转(-1 < 1,有符号)
4.3 循环指令
LOOP target ; CX = CX - 1; if CX ≠ 0 then jump
LOOPE target ; 同上 + ZF = 1 条件
LOOPNE target ; 同上 + ZF = 0 条件
4.4 过程调用
CALL target / RET
CALL PROC1 ; 调用过程(PUSH IP/EIP + JMP)
RET ; 返回(POP IP/EIP)
RET 8 ; 返回 + 清理 8 字节栈参数
5. 栈操作指令
PUSH src / POP dest
PUSH AX ; SP -= 2, [SS:SP] = AX
POP BX ; BX = [SS:SP], SP += 2
PUSHF ; 压入标志寄存器
POPF ; 弹出标志寄存器
PUSHA ; 压入所有通用寄存器(8086)
POPA ; 弹出所有通用寄存器
6. 字符串操作指令
基本指令(需配合 REP 前缀)
MOVSB ; 字节传送:[ES:DI] = [DS:SI], SI++, DI++
MOVSW ; 字传送
MOVSD ; 双字传送
STOSB ; 存储:[ES:DI] = AL, DI++
LODSB ; 加载:AL = [DS:SI], SI++
CMPSB ; 比较:CMP [DS:SI], [ES:DI]
SCASB ; 扫描:CMP AL, [ES:DI]
REP 前缀
REP MOVSB ; 重复 CX 次
REPE CMPSB ; 相等时重复(ZF = 1)
REPNE SCASB ; 不相等时重复(ZF = 0)
示例:内存复制
MOV CX, 100 ; 复制 100 个字节
MOV SI, OFFSET SRC
MOV DI, OFFSET DEST
CLD ; DF = 0(递增)
REP MOVSB ; 执行复制
7. 易混淆指令对比总结
7.1 地址 vs 内容
MOV AX, [BX] ; AX = 内存[BX]的内容
LEA AX, [BX] ; AX = BX(地址值本身)
7.2 有符号 vs 无符号
| 操作 | 无符号 | 有符号 | 关键区别 |
|---|---|---|---|
| 乘法 | MUL | IMUL | 结果高位解释不同 |
| 除法 | DIV | IDIV | 符号位处理不同 |
| 大于 | JA | JG | 基于 CF vs OF+SF |
| 小于 | JB | JL | 基于 CF vs OF+SF |
7.3 移位操作
SHR AL, 1 ; 逻辑右移(高位补 0)
SAR AL, 1 ; 算术右移(保持符号位)
ROR AL, 1 ; 循环右移(无符号扩展)
7.4 跳转指令记忆技巧
- A/B(Above/Below)→ 无符号数
- G/L(Greater/Less)→ 有符号数
- E(Equal)→ 等于条件
8. 标志位影响速查
| 指令类型 | CF | ZF | SF | OF | PF | AF |
|---|---|---|---|---|---|---|
MOV | - | - | - | - | - | - |
ADD/SUB | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
INC/DEC | - | ✓ | ✓ | ✓ | ✓ | ✓ |
MUL/IMUL | ✓* | - | - | ✓* | - | - |
AND/OR/XOR | 0 | ✓ | ✓ | 0 | ✓ | - |
CMP | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
TEST | 0 | ✓ | ✓ | 0 | ✓ | - |
注:仅当结果高位非零时 CF=OF=1
9. 实战示例
9.1 判断奇偶性
TEST AL, 01H ; 测试最低位
JZ EVEN ; 偶数跳转
; 奇数处理
9.2 数组求和
XOR AX, AX ; 清零累加器
MOV CX, 100 ; 数组长度
MOV SI, OFFSET ARRAY
LOOP_SUM:
ADD AX, [SI]
ADD SI, 2
LOOP LOOP_SUM
9.3 快速乘以 5
; AX * 5 = AX * 4 + AX
LEA BX, [AX*4+AX] ; BX = AX * 5(一条指令)
参考资料
- Intel® 64 and IA-32 Architectures Software Developer’s Manual
- 王爽《汇编语言(第3版)》
- AT&T 与 Intel 汇编语法对照