ARM的ATPCS调用约定
ARM的ATPCS调用约定
ATPCS标准,可以理解为ARM是怎么使用堆栈的。
那么在此之前需要熟悉调用约定的知识。X86的栈操作知识等。
调用约定
调用约定分为如下:
cdecl调用约定
该调用约定遵循以下规则
- 参数入栈顺序是从右向左
- 栈平衡是调用者来负责
stdcall 调用约定
- 入栈规则:参数从右向左入栈
- 栈平衡负责:被调用者负责
fastcall调用约定
- 参数入栈顺序:函数的第一个第二个参数通过ecx和edx入栈。x64的结构下还有r8 ,r9 (寄存器),剩余的参数则从右向左入栈。
- 栈平衡:被调用者进行栈平衡。(x64是调用者负责)
返回值的存放:
返回值放在EAX和RAX(x64)中
ARM调用约定
ARM函数之间相互调用遵循的规则就是ATPCS(ARM-Thumb Procedure Call Standard)ATPCS主要是定义了函数调用时参数的传递规则以及函数的返回规则。它类似于X64下的fastcall调用。
它们有个共同的特点就是寄存器多,有大量寄存器可以使用。
传参方式
R0~R3是传递函数的第一个到第四个参数的,超出的部分从右向左通过栈传递
在X64下则是RCX RDX R8 R9寄存器进行参数传递。所以这里很像。
栈平衡
栈平衡是由调用者进行栈平衡的。
结果保存
- 结果为32位整数的时候可以通过寄存器R0来返回
- 结果是64位整数的时候可以通过R0,R1返回
- 结果是浮点数,那么通过浮点数寄存器F0 D0或者S0返回
- 结果是符号浮点数,那么可以通过寄存器F0 - FN或者D0-DN来进行返回
局部变量
R4-R11是用来保存局部变量的,如果用到了那么函数在进入的时候就需要先保存,这点类似于x86环境下的pushad , pushfd等指令,保存寄存器环境。而在返回的时候,这些寄存器的值也要进行恢复。
Thumb 指令只能使用R4-R7 , R11 也可以做FP寄存器。也就是x86的EBP。
返回地址
返回地址使用R14寄存器进行保存(也叫做LR寄存器)
X86的返回地址在栈中进行保存。
栈顶寄存器
R13是作为栈顶寄存器的,也就是SP寄存器。x86下则是ESP
栈基址寄存器
R11作为栈基址寄存器 也就是FP指令。X86下则是EBP。
下一条指令寄存器
R15寄存器,也叫做PC寄存器。是指向下一条要执行指令的,类似于X86下的EIP寄存器
备份寄存器
R12寄存器主要作用于子程序内部的,也叫做IP寄存器。内部过程调用寄存器,可以备份保存SP(R13) LR(R14)寄存器等。
堆栈使用的FD满递减栈,也就是跟X86是一样的。