【发布时间】:2016-12-17 23:30:48
【问题描述】:
我正在了解函数调用在 x86 平台中的工作方式。据我了解 调用函数时发生的步骤:
函数的参数和返回地址被压入堆栈。
然后将当前 EBP 的值压入堆栈。
现在 ESP 已更改(由于步骤 2),EBP 已替换为 ESP,现在它们是 指向(堆栈?)的相同地址。
然后局部变量被推送,函数开始工作。
最后这个函数的局部变量和寄存器都被弹出了。在这个 进程 ESP 也在移动,对吧?
最后,EBP 被当前 ESP 中的值替换
现在 ESP 和 EBP 指向堆栈的相同地址。
所以我的问题是如果以上所有点都正确,否则请纠正我,将如何 该系统在 2 个函数调用的情况下工作。让我解释一下
对于第一个函数调用,ebp 被压入堆栈,并且 esp 和 ebp 相同。
现在增加 esp 以创建第一个函数调用的本地堆栈,例如 foo()。
现在假设有来自 foo() 的第二个函数调用,比如 goo()。
现在将再次发生相同的过程....当前的 ebp 将被推送到堆栈
esp 和 ebp 将变得相同,并且 esp 将递增(从技术上讲, decremented ) 用于 goo() 函数的局部变量。
现在让我们关注函数何时返回。
从 goo() 返回,尤其是随着本地寄存器从堆栈中弹出并在 最后一个 esp 将被分配位置 ebp 持有的值,而不是当前的值 ebp,对吧?
然后会弹出保存 ebp 的位置。
所以我的问题是,如果现在是这种情况,我们已经失去了 函数 foo() 因为 ebp 和 esp 指向 foo() 的 ebp,它将被弹出 foo() 返回...
由于实际情况并非如此,因此我一定遗漏了一些东西。请帮帮我...
谢谢。
【问题讨论】:
标签: x86 return cpu-registers calling-convention