本文主要是介绍【ARM64 常见汇编指令学习 22 -- ARMv8/v9 入栈寄存器介绍】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- ARMv8/v9 入栈寄存器介绍
- 可以不入栈的寄存器
- 需要入栈的寄存器(被调用者保存的寄存器)
- 入栈顺序
- 出栈顺序
- 示例汇编代码
ARMv8/v9 入栈寄存器介绍
在 ARMv8 架构中,函数调用遵循一组称为 AAPCS64 (ARMv8 64-bit Procedure Call Standard)的规则。这个调用约定定义了哪些寄存器是可用于传递函数参数的、哪些需要由调用者保存(caller-saved),以及哪些需要由被调用者保存(callee-saved)。
可以不入栈的寄存器
- 参数寄存器:
X0
至X7
用于传递整数和指针参数,以及返回值。 - 临时寄存器:
X8
至X15
是临时寄存器,被调用者(callee)不需要保存它们。 - 浮点参数寄存器:
V0
至V7
用于浮点参数的传递。
函数调用时,以上寄存器的值通常不需要入栈,除非调用者(caller)希望在函数调用返回后还能再次使用这些寄存器中的值。
需要入栈的寄存器(被调用者保存的寄存器)
- 寄存器
X19
至X29
是被调用者保存寄存器,也称为 Callee-saved 寄存器。如果在函数中使用这些寄存器,你必须在函数入口处将它们推入栈中(保存它们的状态),并在函数退出之前从栈中恢复它们。 - 链接寄存器
LR
(X30
)通常也需要保存,以便在返回时使用。 - 堆栈指针
SP
(X31
或SP_ELx
)用于堆栈操作。 - 浮点/向量寄存器V8
至V15
如果被使用,也需要被保存。
入栈顺序
当一个函数需要保存这些寄存器时,它通常会按照从低寄存器号到高寄存器号的顺序将它们压栈。例如,先保存 X19
,然后是 X20
,一直到 X29
和 LR
。
出栈顺序
在函数返回前,需要从栈中恢复这些寄存器的值。这通常是按照入栈的相反顺序完成的,即从高寄存器号到低寄存器号。例如,先恢复 LR
和 X29
,然后是 X28
,一直到 X19
。
示例汇编代码
// 函数入口
func: STP X29, X30, [SP, #-16]! // 保存帧指针和链接寄存器 STP X19, X20, [SP, #-16]! // 如果需要,保存 callee-saved 寄存器 // 函数体 ... // 函数退出 LDP X19, X20, [SP], #16 // 恢复 callee-saved 寄存器 LDP X29, X30, [SP], #16 // 恢复帧指针和链接寄存器 RET // 返回到调用者
在此示例中,STP
(Store Pair of Registers)和 LDP
(Load Pair of Registers)指令用于同时保存和恢复两个寄存器,[SP, #-16]!
表示预索引递减堆栈指针,而 [SP], #16
表示后索引递增堆栈指针。
请注意,实际的保存操作可能会根据函数的需要来调整哪些寄存器被保存以及它们是否需要被保存。
这篇关于【ARM64 常见汇编指令学习 22 -- ARMv8/v9 入栈寄存器介绍】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!