Aarch64过程调用标准
前言
Aarch64过程调用标准(AAPCS64)描述了在ARM 64位体系结构下应用程序二进制接口(ABI)在过程调用中应遵循的调用约束,涉及寄存器使用规则、堆栈布局、函数参数传递以及返回值保存等内容。
基本程序执行寄存器
ARM 64位处理器中包含了31个64位通用寄存器,依次为r0-r30:在64位上下文中,使用x0-x30的命名引用寄存器;在32位上下文中,则使用w0-w30的命名来使用寄存器。此外,处理器还提供了栈指针寄存器(SP)。对于所有基本程序执行寄存器在过程调用中的作用描述如下表所示:
寄存器名 | 功能描述 |
---|---|
SP | 栈指针寄存器,指向当前堆栈的栈顶 |
r30 | 链接寄存器,用于保存过程调用的返回地址,可使用LR 别名引用 |
r29 | 帧指针寄存器,存放当前过程调用栈帧的起始地址,可使用FP 别名引用 |
r19…r29 | 遵循被调用者保存原则 |
r18 | 平台预留寄存器。必要时可作为临时寄存器使用 |
r17 | IP1 ,内部过程调用寄存器,常用于动态链接中的plt寻址等指令 |
r16 | IP2 ,内部过程调用寄存器,常用于动态链接中的plt寻址等指令 |
r9…r15 | 临时寄存器,理论上遵循调用者保存原则 |
r8 | 间接结果寄存器,一般用来传递间接结果的地址 |
r0…r7 | 用于参数传递以及保存函数调用的返回值 |
运行时堆栈
对于大多数现代处理器架构,基本都是用堆栈来实现过程调用。堆栈是内存的连续区域,可用于存储过程调用中的寄存器状态、局部变量,并在没有足够的参数寄存器可用时传递多余的其它参数。如下是典型ARM程序运行时的堆栈布局:
参数传递
Aarch64同时支持使用寄存器或堆栈进行参数传递。Aarch64标准提供了8个通用寄存器(r0-r7)用于传递函数参数,依次对应于参数1、参数2、参数3…。一般来说,对于只带有少量参数的函数,仅使用寄存器就足够了;超过8个的参数会存放在堆栈中用于传递给子例程。
返回值
用于参数传递的寄存器同时也可用来保存函数的返回值,对于C语言这种函数返回类型基本都是整型数的,r0
寄存器足够使用。
相关参考
- 《Procedure Call Standard for the ARM 64-bit Architecture (AArch64)》