解读 CentOS(或任何 Linux x86/x64 平台)下的反汇编结果,本质上是在“读机器指令对应的汇编语言”。下面我按从工具到语法,再到实战解读的顺序,系统性讲一下。
objdump(最常用)objdump -d test
常用参数:
-d:反汇编可执行代码-M intel:使用 Intel 语法(默认是 AT&T)-S:源代码 + 汇编混合objdump -d -M intel test
gdb(动态调试)gdb ./test
(gdb) disassemble main
或:
(gdb) disas /m main # 带源码
readelf(辅助分析)看符号、段、入口:
readelf -h test
readelf -s test
CentOS 默认是 AT&T 语法,很多人不习惯。
mov %rsp,%rbp
mov 0x8(%rbp),%rax
mov rbp, rsp
mov rax, [rbp+8]
✅ 建议始终加 -M intel
示例(x86-64):
0000000000400526 <main>:
400526: 55 push rbp
400527: 48 89 e5 mov rbp, rsp
40052a: 48 83 ec 10 sub rsp, 0x10
| 部分 | 含义 |
|---|---|
400526 |
指令虚拟地址 |
55 |
机器码 |
push rbp |
汇编指令 |
<main> |
函数名 |
push rbp
mov rbp, rsp
sub rsp, 0x10
作用:
leave
ret
等价于:
mov rsp, rbp
pop rbp
ret
rdi, rsi, rdx, rcx, r8, r9
浮点:xmm0~xmm7
raxxmm0示例:
mov edi, 5
call func
→ func(5)
| 指令 | 含义 |
|---|---|
mov |
数据传送 |
push/pop |
栈操作 |
call |
函数调用 |
ret |
返回 |
lea |
取地址(不是取值) |
cmp |
比较 |
je/jne/jg/jl |
条件跳转 |
test |
位测试(常用于 if) |
int add(int a, int b) {
return a + b;
}
add:
mov eax, edi
add eax, esi
ret
解读:
edi = aesi = beax = a + beax编译器优化后可能:
push rbp示例:
lea eax, [rdi+rsi]
ret
→ 直接算地址并返回
objdump -d -M intel test | less
gdb ./test
break main
run
stepi
(gdb) x/10x $rsp
解读 CentOS 反汇编 = 搞清楚“谁在调用谁、数据从哪来、结果去哪了”
如果你愿意,可以:
我可以逐行帮你解读。