ARM汇编中,栈指针和帧指针有什么区别?

10
我想知道有人能否解释一下在ARM汇编中,堆栈指针(Stack Pointer)和帧指针(Frame Pointer)的区别。
2个回答

9
据我理解,SP始终指向下一个可用的堆栈地址(可能需要先进行预减或预增),该地址将用于推送数据或存储返回地址。
如果函数在执行过程中动态分配了一块存储空间,则SP可能会发生变化。因此,堆栈帧中的数据(例如传递的参数和局部变量)不能通过从SP偏移来可靠地引用,因为SP在函数执行过程中的值不保证相同。
另一方面,FP在整个函数执行过程中保证具有相同的值,因此可以通过从FP硬编码的偏移量访问所有局部数据。 FP设置为堆栈帧内的固定值,通常在最后一个传递的参数之后。

这是我找到的一张图片,可能会很有用。您可以看到,从FP偏移总是正确的,但从SP偏移将取决于动态区域的大小,因此在分配运行时变量空间的函数(如C99 VLA / alloca)中不能硬编码。https://www.cs.purdue.edu/homes/hosking/502/spim/node23.html。不这样做的函数可以优化掉帧指针(在将高级源语言(如C)转换为汇编时,优化编译器会自动完成这项工作)。


在arm64汇编中,我看到在函数开始时,sp被减少以容纳函数中的所有堆栈变量,并且fp也被设置为与sp相同的值。在函数中,对于堆栈变量访问,使用sp相对寻址,并且参数通过寄存器传递。因此,在这种情况下,fp和sp是相同的(但我猜通常情况下,sp可以在函数中上下移动,就像答案所说的那样)。但是,如果堆栈用于传递变量,我没有检查确切发生了什么。 - Chan Kim

1
ARM有通用寄存器,它们都是相同的,所以为特定目的(如堆栈指针和帧指针)指定特定的寄存器只是一种约定。
在ARM64上的约定是使用x31作为堆栈指针,使用x29作为帧指针。
在ARM32上的约定是使用r13作为堆栈指针。

ARM32 的惯例是使用 r13 作为堆栈指针,r11 作为帧指针。但正如您所提到的,这是编译器制造商使用的惯例。在纯汇编编程时,开发人员可以将任何寄存器用于任何他们喜欢的目的。 - tum_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接