ebp 函数堆栈esp_如果esp指向堆栈的顶部,ebp指向哪里?esp和ebp如何协同工作?

在每个函数的开头,ebp指向调用函数需要它的地方,它与当前函数无关,直到当前函数的代码选择使用它。ebp只是一个堆栈帧指针,以防您选择有一个堆栈帧。它的概念是,当您可以继续使用esp添加或删除堆栈上的项时,您可以使用ebp为您的函数提供对堆栈的非移动引用。如果您不使用堆栈指针而继续使用esp作为对堆栈的引用,那么堆栈上的某个特定项将在整个过程中结束函数相对于esp不同。如果在开始使用堆栈之前设置了ebp(而不是保存ebp),则与函数关心的堆栈上的参数(如传递的参数、局部变量等)有一个固定的相对地址。

您可以完全自由地在函数中使用eax或edx或任何其他寄存器作为堆栈帧指针,ebp作为一个通用寄存器供您用于堆栈帧,因为x86历来有堆栈依赖关系(返回地址和旧的调用约定是基于堆栈的)。其他具有更多寄存器的指令集可能只需为编译器实现选择一个寄存器作为函数指针/堆栈帧指针。如果您可以选择使用堆栈帧。它会烧掉一个你可以用来做其他事情的寄存器,消耗更多的代码和执行时间。与使用其他通用寄存器一样,ebp根据当前使用的调用约定是非易失性的,您需要保存它并按原来的方式返回。所以它指向的是特定于函数的。当你的函数被输入时它所指向的是特定于调用函数的。

可以选择一个编译程序如何选择一个特定的ebp框架来实现。如果它在启用时总是以同样的方式使用,那么通过该工具链,您可能有一个调试器或其他工具可以利用它。例如,如果函数中的第一件事是在堆栈上推送ebp,那么任何函数中相对于ebp的调用函数的返回地址是固定的(除非有一些尾部优化,否则可能是调用者(调用者的)的调用者)。您正在为此特性烧录寄存器、堆栈空间和代码空间,但是,与调试编译一样,您可以在开发期间使用堆栈框架编译以使用这些功能。

之所以从push开始,是使用帧指针并定义一致位置的好方法。第一件事就是把它推到堆栈上1)保留ebp,这样就不会使调用函数崩溃2)在ebp下面定义一个一致的引用点地址是返回地址和在函数持续期间以固定偏移量调用参数。对于这样的方案,局部变量位于ebp之上的固定地址。编译器和人类一样,完全不需要这样做,我的第一个参数可能在代码中的某个时间点在esp-20,然后我可能会在堆栈上多推8个字节,现在相同的参数在esp-28上,就这样编码吧。但出于调试的目的,调试生成的代码,有时会在固定偏移量处查找返回地址。烧录另一个寄存器是我懒惰的,但是,肯定可以帮助调试和提高编译器输出的质量。更快地发现编译器输出中的错误,帮助那些试图阅读代码的人更快地理解它。正确使用堆栈帧指针时,在设置和清理堆栈帧指针的点之间的函数持续时间内,所有参数和局部变量都位于堆栈帧指针的固定偏移量处。按指针保存它设置帧指针到堆栈指针有或没有偏移。返回前帧指针的弹出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值