在两次函数调用期间,EBP和ESP在堆栈中的行为

我正在浏览函数调用如何在x86平台上工作。 据我所知,下面的步骤发生在一个函数被调用时:

  • 函数的参数和返回地址被压入堆栈。

  • 那么当前EBP的值被推入堆栈。

  • 现在ESP已经改变(由于步骤2),EBP被ESP取代,现在它们指向相同的地址(Stack?)。

  • 然后局部变量被推送并且函数做它的工作。

  • 最后,该函数的局部变量被调用,寄存器也被调用。 在这个过程中,ESP也在移动,对吗?

  • 最后,EBP将被替换为当前ESP所持有的价值

  • 现在ESP和EBP指向堆栈的相同地址。

  • 所以我的问题,如果所有上述观点是正确的,否则请纠正我,这个系统如何在2个函数调用的情况下工作。 让我解释

  • 对于第一个函数调用,ebp被推送到堆栈,esp和ebp被设置为相同。

  • 现在esp会增加以创建第一个函数调用的本地堆栈,如foo()。

  • 现在让我们说foo()有第二个函数调用,比如说goo()。

  • 现在再次发生同样的过程....当前ebp将被推入堆栈

  • esp和ebp将会变成相同,esp将会增加(技术上,递减)goo()函数的局部变量。

  • 现在我们着重讨论函数何时返回。

  • 从goo()返回,尤其是当本地寄存器从堆栈中移出时esp增量,最后esp将被赋予位置ebp保存的值而不是当前ebp的值,对吧?

  • 那么持有ebp的位置将会被锁定。

  • 所以我的问题是,如果现在是这种情况,我们已经失去了函数foo()的堆栈的开始,因为ebp和esp指向foo()的ebp,只要foo()返回,它就会被调用。 ..

    由于这不是实际发生的事情,我必须错过一些东西。 请帮帮我...

    谢谢。


    我假设你在谈论cdecl(https://en.wikipedia.org/wiki/X86_calling_conventions#cdecl)调用约定(c中经常使用的约定)。

    %ebp是基址指针寄存器,它是被保存的,这意味着调用者可以假定被调用者不会修改其值,因此调用者可以假定%ebp将始终引用其堆栈的基础。

    %esp是堆栈指针寄存器,它也被保存,但是,由于调用者将堆栈%esp上被调用者的参数压入了递减量,所以当被调用者返回时它需要递增。 我认为这就是你的问题潜伏的地方,%esp的值只会增加到足以释放分配的参数,而不是返回到堆栈的底部。

    %ebp和%esp有效地指向堆栈的基础和“顶部”。 没问题

    链接地址: http://www.djcxy.com/p/80387.html

    上一篇: Behaviour of EBP and ESP in stack during 2 function calls

    下一篇: Understanding executing a function at the machine level