如何解决堆栈指针和基指针
您好,我想问一下 EBP 和 ESP 寄存器在程序执行过程中是如何初始化和更新的。
我下面有一张图,作者解释说,当进入一个新函数时,首先将参数压入黄色区域所示的堆栈,然后更新基指针EBP并存储前一个函数的基指针,其次是堆栈为局部变量和返回地址分配更多资源。
我想知道在进入新函数时简单地更新基指针,然后为前一个函数的基指针寄存器地址分配内存,然后是参数,局部变量和返回值是不是更容易?而不是将 EBP 放在函数的堆栈帧中间。
我的另一个问题是,返回地址值在前一个函数中究竟指向哪里,是在前一个函数的末尾,还是在前一个函数的开头?
我的另一个问题是,如果您已经存储了前一个函数的返回地址,那么存储前一个函数基指针寄存器有什么意义?
我从指针中得到的想法是,您本质上只想将它们用作访问函数本地资源的引用,您可以使用返回地址
谢谢
解决方法
要从函数返回,您需要(至少)恢复两件事。
一个是指令指针所在的位置,即您运行它的下一条指令所在的位置。
另一个是栈指针所在的位置,你正在操作的数据所在的位置。
(根据调用约定,寄存器可能也需要重置,但我不知道这里的细节)。
返回地址——指令指针——指向从调用返回时代码应该继续执行的位置。这通常不是调用函数的开始或结束,而是调用后的“下一条指令”。 (但不是真的;它指向处理函数返回的代码,这在某些调用约定中确实有效)。
代码调用一个函数必须更新堆栈指针,以便被调用的函数知道它的堆栈参数在哪里,并为被调用的函数返回提供足够的信息。
调用的函数不需要在内部进行。它(好吧,编写它的编译器知道)它在堆栈中放置了哪些变量,以及它们有多大。在函数体中,堆栈上的变量集可能会随时间变化。因此更新堆栈指针毫无意义,甚至会使偏移量计算变得更加复杂(因为它们会不断变化,而不是对于给定的“变量”保持不变)并且让汇编编写者感到困惑。
访问堆栈的代码无论如何都会使用偏移量。不改变堆栈指针比改变堆栈指针所做的工作更少,而且做更少的工作通常比做更多的工作更快。
所以除非你需要改变它,否则你不用管堆栈指针。
返回地址对于访问可变数据没有用。返回地址通常指向只读机器代码,而不是堆栈上的可变状态。
现在,有大量的调用约定。他们中的许多人做的事情略有不同。哪些参数进入堆栈,哪些存储在寄存器中,什么样的参数去哪里,以及谁重置堆栈指针(调用者或被调用者)等都可能有所不同。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。