x86汇编:为什么我需要堆栈帧?

时间:2013-06-21 16:11:16

标签: assembly x86 nasm

在大多数x86汇编(特别是NASM)代码示例中,我看到(即使是由GCC生成的代码样本),我看到了所谓的“堆栈帧的设置”。像这样:

main: 
        /*setting the stack frame*/
        push    ebp     
        mov     ebp,esp

        ...
        code goes here
        ...

        /*removing the stack frame*/
        mov     esp, ebp
        pop     ebp

我对此做法有3个问题:

  1. 如果我的代码没有触及堆栈,那么如上所述设置/删除堆栈帧是完全没用的,对吗?

  2. 即使我的代码使用了堆栈,只要弹出我推送的所有东西(基本上都是堆栈),那么再次设置堆栈框架是完全没用的,对吗?

  3. 我认为这样做的唯一目的就是保存ESP的价值,这样我就可以在我的代码上玩它而不用担心搞乱事情了,一旦完成,我只需恢复它原始价值。这是堆栈框架设置的目的还是我遗漏了什么?

  4. 由于

3 个答案:

答案 0 :(得分:5)

嗯,事实上,你不需要堆栈帧。

当您保存寄存器并将局部变量存储在堆栈中时,堆栈帧很方便 - 使编写和调试更容易:您只需将ebp设置为堆栈中的固定点并使用ebp处理所有堆栈数据。最后恢复esp会更容易。

此外,调试器通常期望存在堆栈帧,否则您可能会获得不准确的堆栈调用。

所以,1的答案是肯定的,2和3的答案在上面。

答案 1 :(得分:3)

你基本上是对的。

但是,即使您不需要固定的堆栈引用来访问参数和本地,堆栈帧也有一定的好处。特别是在那里使用它们可以实现精确的堆栈遍历,以便为调试目的生成堆栈跟踪。

答案 2 :(得分:2)

这是按惯例完成的。 C语言函数使用堆栈帧来访问发送到函数的参数,以及设置动态局部变量。这就是他们在您正在查看的示例代码中执行此操作的原因。当然,如果你想按自己的方式去做,你可以,但是你将无法从C等调用你的代码。

编辑:我也很确定有编译器实现了不同的调用约定来优化它,也许根本不创建一个框架。所以基本上,你是对的。堆栈帧不是必需的。

相关问题