我已经读过,使用基址寄存器来跟踪堆栈帧并不是必需的。我不明白编译器是如何实现这一点的,是否将堆栈帧大小存储在某处并读取它并将其添加到%rsp中?
答案 0 :(得分:5)
这通常也是必要的,只要您处于两种情况中的任何一种情况:
rsp
仅按已知金额更改rsp
永远不会改变(你可以说这是一个已知的数量,金额是0)通常在x64代码中,rsp
仅在序言,结尾和隐式调用/返回时更改。任何临时空间都是预先分配的,并通过索引到堆栈帧中进行寻址(大多数情况下一样,除了偏移量来自rsp
而不是基本指针 - 如果{{1}没有任何区别不会改变),而不是通过推动和弹出。在这种情况下,很容易恢复旧的rsp
,只需添加在序言中减去的相同内容。
或者,这尤其适用于有redzone的linux,对于许多叶子函数,你可以完全不改变rsp
。在这种情况下,您可能甚至不需要序言或结语,只需要一堆正常的代码,然后是rsp
。
显然ret
(和其他分配可变数量的堆栈空间的构造)会破坏它,并且会再次使用帧指针。