【问题标题】:'push ebp' 'pop ebp' not used but still breaks code when removed.'push ebp' 'pop ebp' 未使用,但删除后仍会破坏代码。
【发布时间】: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.

标签: assembly x86 arguments


【解决方案1】:

如果不使用则不需要推送。

在您的优化代码中,您使用的是原始偏移量 0c08ebp 被推送时是正确的。

你必须分别使用0804,当你没有推送任何东西并且esp仍然有它原来的函数入口值。

【讨论】:

    猜你喜欢
    • 2011-08-23
    • 2011-04-07
    • 2012-04-03
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    相关资源
    最近更新 更多