由于 ARM64 中缺乏 PUSH 和 POP 指令,我在理解 SP 在 ARM64 中如何工作时遇到了问题。
如果我要 PUSH/POP,SP 会减少/增加 4、8 或 16 个字节吗?
我正在阅读文档说堆栈帧必须按16字节对齐,但是当我调试时,情况似乎并非如此。
堆栈是向上还是向下增长完全取决于您正在查看的系统的 ABI。也就是说,我所处理的所有 arm64 代码都有向下增长的堆栈。
这样,常见的推送将如下所示:
stp x29, x30, [sp, -0x10]!
还有像这样的常见流行音乐:
ldp x29, x30, [sp], 0x10
这显然会同时压入/弹出两个寄存器,从而一次修改堆栈指针 16 个字节,这将我们带到下一部分:
堆栈对齐检查。堆栈指针是否必须与 16 字节边界对齐“也”取决于您正在使用的 ABI,但它是可以配置的实际硬件功能。
请参阅 ARMv8 参考手册,SCTLR_EL[123]
包括针对每个异常级别打开或关闭此功能的位。引用自
SCTLR_EL1
,例如:SA0,位 [4]SP EL0 的对齐检查启用。当设置为 1 时,如果加载或存储 在 EL0 执行的指令使用 SP 作为基地址,而 SP 不是 对齐到 16 字节边界,则 SP 对齐错误异常是 生成的。有关详细信息,请参阅第 D1-2333 页上的 SP 对齐检查。 当实现ARMv8.1-VHE时,HCR_EL2.{E2H, TGE}的值为 {1, 1},该位对 EL0 处的执行没有影响。 在 PE 重置为 EL1 的系统中,该字段重置为 建筑上未知的价值。 SA,位 [3] SP 对齐检查启用。当设置为 1 时,如果加载或存储指令 在 EL1 处执行使用 SP 作为基地址,并且 SP 未对齐 16 字节边界,则生成 SP 对齐错误异常。为了 更多信息,请参阅D1-2333 页上的 SP 对齐检查。 当实现ARMv8.1-VHE时,HCR_EL2.{E2H, TGE}的值为 {1, 1},该位对PE没有影响。 在 PE 重置为 EL1 的系统中,该字段重置为 建筑上未知的价值。