从 C++ 看 x86 反汇编
学习汇编的一种好方法是写简单 C++,再观察反汇编。
int add(int a, int b) {
return a + b;
}
编译器可能生成类似:
lea eax, [rdi + rsi]
ret
lea 虽然名字是 load effective address,但也常被编译器用来做简单算术。
优化等级
不同优化等级生成的汇编差异很大。
调试学习时可以从 -O0 开始,再对比 -O2。
图片来源:Wikimedia Commons,Intel 80486DX2 处理器照片,用来补充 x86 硬件背景。
为什么反汇编看起来不像源码
编译器不是逐行翻译 C++。它会做优化、重排、内联和删除无用代码。因此你看到的汇编可能和源码结构差异很大。
比如简单加法可能不用 add,而用 lea:
lea eax, [rdi + rsi]
lea 不访问内存,只计算地址表达式。编译器喜欢用它做无副作用的整数计算。
学习方法
我建议准备几个非常小的函数:
- 两个整数相加。
- if/else。
- for 循环。
- 访问数组。
- 调用另一个函数。
分别用 -O0 和 -O2 编译,再对比反汇编。这样能直观看到优化器做了什么。
评论
...正在读取评论。