Appearance
x86汇编语言基础
考情分析
程序的机器级代码表示是 2022 年新增考点,但相关知识早在 2012、2014、2015、2017 年就以综合题出现。统考主要考查 x86 指令(Intel 格式),偶尔涉及 MIPS(会附功能说明)。
x86 通用寄存器
x86 有 8 个 32 位通用寄存器:
| 寄存器 | 低16位 | 高/低8位 | 常见用途 |
|---|---|---|---|
| EAX | AX | AH/AL | 累加器,函数返回值 |
| EBX | BX | BH/BL | 基址寄存器 |
| ECX | CX | CH/CL | 计数器(循环/移位) |
| EDX | DX | DH/DL | 数据寄存器,乘除法扩展 |
| ESI | SI | — | 源变址寄存器 |
| EDI | DI | — | 目的变址寄存器 |
| EBP | BP | — | 基址指针(栈帧底部) |
| ESP | SP | — | 栈指针(栈顶) |
EBP 和 ESP 有专用功能,其余寄存器用途较灵活。
操作数标记
<reg>:寄存器(如 eax、ebx)<mem>:内存地址(如[eax]、[ebp-8]、dword ptr [eax+ebx*4+8])<con>:立即数/常数
两个操作数不能同时为内存。
常用指令
以下使用 Intel 格式(目的操作数在前,源操作数在后)。
数据传送指令
| 指令 | 语法 | 功能 |
|---|---|---|
| mov | mov dst, src | 将 src 复制到 dst |
| push | push src | ESP-4,再将 src 压入栈顶 |
| pop | pop dst | 弹出栈顶到 dst,ESP+4 |
| lea | lea dst, [addr] | 将有效地址(非内存内容)加载到 dst |
asm
mov eax, ebx ; R[eax] <- R[ebx]
mov eax, [ebp+8] ; R[eax] <- M[R[ebp]+8]
mov [ebp-4], eax ; M[R[ebp]-4] <- R[eax]
push eax ; ESP-4, M[ESP] <- R[eax]
pop ebx ; R[ebx] <- M[ESP], ESP+4
lea eax, [edx+eax*2+8] ; R[eax] <- R[edx]+R[eax]*2+8(计算地址,不访存)lea 是"取地址"指令,常被编译器用来做加法运算(如 lea eax, [edx+eax] 等价于 add eax, edx)。
算术与逻辑运算指令
| 指令 | 功能 | 示例 |
|---|---|---|
| add | 加法,结果存入第一操作数 | add eax, 10 |
| sub | 减法 | sub eax, ebx |
| inc/dec | 自增/自减 1 | inc eax |
| imul | 有符号乘法 | imul eax, ebx |
| idiv | 有符号除法,被除数为 edx:eax | idiv ecx |
| neg | 取负(补码) | neg eax |
| and/or/xor | 按位与/或/异或 | and eax, 0FH |
| not | 按位取反 | not eax |
| shl/shr | 逻辑左移/右移 | shl eax, 1 |
| sal/sar | 算术左移/右移 | sar eax, 2 |
asm
xor edx, edx ; 将 edx 清零(常见技巧)
imul esi, edi, 25 ; R[esi] <- R[edi] * 25
idiv ebx ; eax <- edx:eax / ebx(商),edx <- 余数控制流指令
| 指令 | 功能 |
|---|---|
| jmp label | 无条件转移到 label |
| cmp a, b | 计算 a-b 并设置标志位,不保存结果 |
| test a, b | 计算 a AND b 并设置标志位,不保存结果 |
| je/jz | 相等(ZF=1)时转移 |
| jne/jnz | 不等(ZF=0)时转移 |
| jg/jge | 大于/大于等于时转移(有符号) |
| jl/jle | 小于/小于等于时转移(有符号) |
| ja/jae | 高于/高于等于时转移(无符号) |
| jb/jbe | 低于/低于等于时转移(无符号) |
| call label | 将返回地址压栈,转移到 label |
| ret | 弹出返回地址,转移回调用点 |
asm
cmp eax, ebx
jle done ; 若 eax <= ebx,转移到 done
test eax, eax
jz xxxx ; 若 eax == 0,转移到 xxxxAT&T 格式 vs Intel 格式
| 区别 | AT&T | Intel |
|---|---|---|
| 操作数顺序 | 源, 目的 | 目的, 源 |
| 寄存器 | %eax | eax |
| 立即数 | $100 | 100 |
| 内存引用 | (%eax) | [eax] |
| 长度后缀 | movl(32位) / movw(16位) / movb(8位) | dword ptr / word ptr / byte ptr |
| 复杂寻址 | 8(%edx, %eax, 2) | [edx+eax*2+8] |
统考通常使用 Intel 格式。
对比示例:
| AT&T | Intel | 含义 |
|---|---|---|
movl $100, %eax | mov eax, 100 | |
movl %eax, (%ebx) | mov [ebx], eax | |
movl %eax, -8(%ebp) | mov [ebp-8], eax |
考点清单
- x86 有 8 个 32 位通用寄存器,EBP 为栈帧基址,ESP 为栈顶指针
- 两个操作数不能同时为内存
- lea 是取有效地址,不访存,常被用作加法/乘法
- call = push 返回地址 + jmp 目标;ret = pop 返回地址 + jmp
- cmp 和 test 只设标志位不保存结果,配合 jcondition 使用
- 有符号比较用 jg/jl/jge/jle,无符号比较用 ja/jb/jae/jbe