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寄存器进行参数传递。所以这里很像。

  • 栈平衡

    栈平衡是由调用者进行栈平衡的。

  • 结果保存

    1. 结果为32位整数的时候可以通过寄存器R0来返回
    2. 结果是64位整数的时候可以通过R0,R1返回
    3. 结果是浮点数,那么通过浮点数寄存器F0 D0或者S0返回
    4. 结果是符号浮点数,那么可以通过寄存器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是一样的。