1
3
在第一种情况下,你不在乎保存——这是切入点。你在捣乱
你只需要对世界有一个相对的了解。帧指针通常只是为了使编译器作者的工作更容易,实际上它通常只是为了浪费许多指令集的寄存器。也许是因为一些老师或教科书是这样教的,没有人问为什么。
对于编码健全性、编译器作者的健全性等,如果您需要在函数期间使用堆栈来拥有一个基址,从该基址偏移到堆栈的某个部分,那么这是可取的。或者至少在设置之后和清理之前。这可以是堆栈指针(sp)本身,也可以是帧指针,有时从指令集可以明显看出。有些堆栈向下扩展(在地址空间中接近零),堆栈指针在中只能有正偏移量
总之,为了保持理智,您需要一个参考点来抵消堆栈中的项目,更痛苦但使用更少内存的方法是在进行时添加和删除内容:
做更多的工作,但可以使程序(编译器)保持跟踪,并且比人工更不容易出错,但在调试编译器输出(人工)时,更难跟踪。因此,通常我们燃烧堆栈空间,并有一个参考点。帧指针可用于使用基指针(bp)分离传入参数和局部变量,例如,将其作为函数中的静态基址,以及
不要把你们在课本、白板(或StackOverflow中的答案)上看到的东西当成福音。仔细思考问题,并考虑其他选择。
在第一个示例中
然而,在函数中,基于调用约定,我们假设
通过推动
|
2
1
这个
i386 System V ABI doc
建议(在第节中
2.3.1初始堆栈和寄存器状态
)您可能希望将%ebp设为零以标记最深的堆栈帧。(即在第一次
不,与其他一些x86系统不同的是 i386 System V ABI 不需要太多关于堆栈帧布局的信息。(Linux使用System V ABI/调用约定,您正在使用的书(PGU)是针对Linux的。)
在某些调用约定中,设置
i386 SysV ABI定义了一种用于堆栈展开的替代机制,该机制使用另一节中的元数据使帧指针成为可选的(
如果您想在当前gdb中使用传统的帧漫游,您必须自己定义一个gdb函数,如
gdb backtrace by walking frame pointers
或
Force GDB to use frame-pointer based unwinding
. 或者如果你的可执行文件没有
如果使用
IIRC,
是的,它会工作得很好。事实上
setting up
出于同样的原因,遵守
但是您可以通过使用
或者延迟保存任何寄存器,直到为局部变量保留空间之后,这样我们就不会用掉任何位置(除了ret addr)和我们不想处理的保存值。
但是如果你要这么做,使用
这些例子都是人为的;除非是数组,否则通常不需要太多的局部空间,然后使用索引寻址模式或指针,而不仅仅是相对于
不过,AVX512 compressed disp8在很大程度上击败了64字节AVX512向量的这一论点。(但32位模式下的AVX512仍然只能使用8个向量寄存器,即zmm0-zmm7,因此很容易溢出一些。在64位模式下,只能使用x/ymm8-15和zmm8-31。) |
Dusan · 调用函数时保存状态寄存器 6 年前 |
Bilal · 在C中调用存储Oracle过程# 7 年前 |
LemusThelroy · Python-从其他类中的方法检索值 9 年前 |
vandale · x64程序集中的堆栈对齐 11 年前 |
user2402179 · 对于Windows程序的调用约定,最好声明什么? 11 年前 |