【发布时间】:2017-09-26 02:58:20
【问题描述】:
我编译了:
"
int x_add(int a, int b)
{
return a+b;
}
"
得到了
"
push ebp
mov ebp,esp
mov edx,[ebp+08]
mov eax,[ebp+0c]
pop ebp
ret
"
我将程序集简化为
"
mov eax,[esp+0c]
add eax,[esp+08]
ret
"
当我运行 "x_add(1, 1);" 时,它返回 -1
所以我替换了代码,试图找出问题所在。
"
push ebp
mov eax,[esp+0c]
add eax,[esp+08]
pop ebp
ret
"
按预期工作,返回 1+1=2。 那么为什么在代码中从未使用过 ebp 必须在开头推送然后在末尾弹出呢?
【问题讨论】:
-
所以.. 如果没有 push/pop,您是否没有注意到 esp 的值(以及用于寻址的偏移量)与 push/pop 不同,对吧?您做过,以交互方式调试它,对吗?短版:
push ebp修改了esp,所以如果你删除了 push/pop,你也必须调整你的偏移量。 -
是的,对调试器来说有点新。 IDA 有故障,当我断点代码块时,代码块会跳过代码。我正在使用 Cheat 引擎,没想到要检查堆栈指针。
-
如果你要编译启用优化的代码,它会更简单,更容易理解。
-
谢谢科迪。我正在学习 x86,接下来将尝试查看优化代码和 g++ 输出之间的差异。
-
基本上,分析调试代码(从禁用优化的编译器中得到的)是浪费时间。有很多噪音,还有很多没有意义的东西。这不是学习/理解汇编语言的好方法。 Here's a side-by-side comparison.