跳到主要内容

x86 汇编速查表

本章提供 x86 汇编常用指令、寄存器和概念的快速参考。

通用寄存器

x86-64 寄存器

64 位32 位16 位8 位低8 位高用途
RAXEAXAXALAH累加器、返回值
RBXEBXBXBLBH基址寄存器
RCXECXCXCLCH计数器
RDXEDXDXDLDH数据寄存器
RSIESISISIL-源变址
RDIEDIDIDIL-目标变址
RBPEBPBPBPL-栈帧指针
RSPESPSPSPL-栈指针
R8-R15R8D-R15DR8W-R15WR8B-R15B-通用寄存器

调用约定(Linux x86-64)

寄存器用途保存者
RAX返回值调用者
RDI第 1 个参数调用者
RSI第 2 个参数调用者
RDX第 3 个参数调用者
RCX第 4 个参数调用者
R8第 5 个参数调用者
R9第 6 个参数调用者
RBX通用被调用者
RBP栈帧被调用者
R12-R15通用被调用者
R10-R11临时调用者

标志寄存器

标志名称含义
CF进位标志无符号溢出
ZF零标志结果为零
SF符号标志结果为负
OF溢出标志有符号溢出
PF奇偶标志1 的个数为偶
AF辅助进位低 4 位进位
DF方向标志字符串方向

数据传送指令

mov     dest, src       ; 复制数据
movzx dest, src ; 零扩展传送
movsx dest, src ; 符号扩展传送
xchg op1, op2 ; 交换
lea dest, [addr] ; 加载有效地址

push src ; 压栈
pop dest ; 出栈
pushf/popf ; 标志寄存器操作

算术指令

add     dest, src       ; 加法
adc dest, src ; 带进位加法
sub dest, src ; 减法
sbb dest, src ; 带借位减法
inc dest ; 自增
dec dest ; 自减
neg dest ; 取负

cmp op1, op2 ; 比较(设置标志位)

mul src ; 无符号乘法(RDX:RAX = RAX * src)
imul dest, src ; 有符号乘法
div src ; 无符号除法(RAX = RDX:RAX / src)
idiv src ; 有符号除法

逻辑指令

and     dest, src       ; 与运算
or dest, src ; 或运算
xor dest, src ; 异或运算
not dest ; 取反
test op1, op2 ; 测试(AND 但不保存结果)

移位指令

shl/shr dest, count     ; 逻辑左移/右移
sal/sar dest, count ; 算术左移/右移
rol/ror dest, count ; 循环左移/右移
rcl/rcr dest, count ; 带进位循环移位

条件跳转指令

常用条件跳转

指令条件描述
JMP无条件无条件跳转
JE/JZZF=1相等/零
JNE/JNZZF=0不等/非零
JL/JNGESF≠OF有符号小于
JLE/JNGSF≠OF 或 ZF=1有符号小于等于
JG/JNLESF=OF 且 ZF=0有符号大于
JGE/JNLSF=OF有符号大于等于
JB/JNAE/JCCF=1无符号小于
JBE/JNACF=1 或 ZF=1无符号小于等于
JA/JNBECF=0 且 ZF=0无符号大于
JAE/JNB/JNCCF=0无符号大于等于
JSSF=1为负
JNSSF=0为正
JOOF=1溢出
JNOOF=0无溢出

条件设置指令

setz/sete   dest        ; 等于时设置为 1
setnz/setne dest ; 不等于时设置为 1
setl/setg dest ; 有符号小于/大于
setb/seta dest ; 无符号小于/大于

条件传送指令

cmove/cmovz  dest, src  ; 相等时传送
cmovne/cmovnz dest, src ; 不等时传送
cmovl/cmovg dest, src ; 有符号小于/大于时传送
cmovb/cmova dest, src ; 无符号小于/大于时传送

循环指令

loop    label           ; RCX--,若 RCX≠0 则跳转
loope/loopz label ; RCX--,若 RCX≠0 且 ZF=1 则跳转
loopne/loopnz label ; RCX--,若 RCX≠0 且 ZF=0 则跳转

字符串指令

movsb/w/d/q             ; 传送字节/字/双字/四字
cmpsb/w/d/q ; 比较字节/字/双字/四字
scasb/w/d/q ; 扫描字节/字/双字/四字
stosb/w/d/q ; 存储字节/字/双字/四字
lodsb/w/d/q ; 加载字节/字/双字/四字

rep ; 重复(RCX 次)
repe/repz ; 相等时重复
repne/repnz ; 不等时重复

cld ; DF=0(递增方向)
std ; DF=1(递减方向)

过程调用指令

call    addr            ; 调用过程
ret ; 返回
ret n ; 返回并清理 n 字节参数
leave ; 恢复栈帧(mov rsp,rbp; pop rbp)

寻址模式

[imm]                   ; 直接寻址
[reg] ; 寄存器间接寻址
[reg + disp] ; 寄存器相对寻址
[reg1 + reg2] ; 变址寻址
[reg1 + reg2*scale] ; 比例变址寻址
[reg1 + reg2*scale + disp] ; 完整寻址
[rip + disp] ; RIP 相对寻址

比例因子:1, 2, 4, 8

Linux 系统调用(x86-64)

系统调用约定

寄存器用途
RAX系统调用号
RDI第 1 个参数
RSI第 2 个参数
RDX第 3 个参数
R10第 4 个参数
R8第 5 个参数
R9第 6 个参数
RAX返回值

常用系统调用

编号名称描述
0read读取文件
1write写入文件
2open打开文件
3close关闭文件
9mmap内存映射
39getpid获取进程 ID
57fork创建进程
59execve执行程序
60exit退出进程
62kill发送信号

NASM 伪指令

数据定义

db      value           ; 定义字节
dw value ; 定义字
dd value ; 定义双字
dq value ; 定义四字

resb count ; 保留字节
resw count ; 保留字
resd count ; 保留双字
resq count ; 保留四字

equ value ; 定义常量
times n db value ; 重复定义

段定义

section .data           ; 已初始化数据段
section .bss ; 未初始化数据段
section .text ; 代码段
section .rodata ; 只读数据段

其他伪指令

global  symbol          ; 导出符号
extern symbol ; 导入符号
align n ; 对齐
%define name value ; 定义宏

常用技巧

快速清零

xor eax, eax            ; EAX = 0
xor rax, rax ; RAX = 0

快速判断零

test eax, eax           ; 检查 EAX 是否为 0
jz is_zero

快速乘除

shl eax, 1              ; EAX * 2
shl eax, 2 ; EAX * 4
shl eax, 3 ; EAX * 8

shr eax, 1 ; EAX / 2(无符号)
sar eax, 1 ; EAX / 2(有符号)

lea eax, [eax + eax*2] ; EAX * 3
lea eax, [eax + eax*4] ; EAX * 5

绝对值

; EAX 的绝对值
cdq ; 符号扩展到 EDX
xor eax, edx ; 如果为负,取反
sub eax, edx ; 如果为负,加 1

最小/最大值

; EAX = max(EAX, EBX)
cmp eax, ebx
cmovl eax, ebx

; EAX = min(EAX, EBX)
cmp eax, ebx
cmovg eax, ebx

编译命令

NASM 编译

# 生成 64 位 ELF 目标文件
nasm -f elf64 program.asm -o program.o

# 生成 32 位 ELF 目标文件
nasm -f elf32 program.asm -o program.o

# 生成列表文件
nasm -f elf64 -l program.lst program.asm

链接

# 链接为可执行文件
ld program.o -o program

# 链接 C 库
gcc program.o -o program

# 静态链接
ld program.o -o program -lc -static

调试

# 使用 GDB 调试
gdb ./program

# 常用 GDB 命令
break main # 设置断点
run # 运行
info registers # 查看寄存器
x/10i $rip # 查看指令
stepi # 单步执行
continue # 继续执行

指令长度

指令类型长度
前缀0-4 字节
操作码1-3 字节
ModR/M0-1 字节
SIB0-1 字节
偏移量0-4 字节
立即数0-4 字节

总长度:1-15 字节