AAPCS全称Procedure Call Standard for the ARM Architecture,是ARM架构下应用程序例程调用的二进制接口规范。它的前身是著名的ATPCS。
这个规范的目的是使不同程序模块可以分别编译,在二进制级别直接配合使用。目前ARM编译器均采用了这一标准。因此,当在ARM架构进行调试、逆向工程、漏洞分析、病毒分析时,如果对这些调用规范比较熟悉,就能快速识别出函数调用、参数和返回值等,提高效率。
名词解释:
例程(routine)、子例程(subroutine):对于一段可以调用、可以返回、保证栈平衡的代码片段,例程指调用者,子例程指被调用者。
过程(procedure):不返回结果值的例程。
函数(function):返回结果值的例程。
变量大小、内存对齐、字节序、复合类型等:略。
寄存器:
ARM中有16个通用寄存器r0 – r15。其中:
r0 – r3:用于传递参数、返回函数结果,因此又名a0 – a3。在例程内部也被用于保存临时结果;
r4 – r11:用于保存例程内的局部变量值,有名v0 – v8。其中,r9(v6)是一个平台相关的值,不同的ARM平台必须为这个寄存器赋予特殊的含义;
r12 – r15:有专门的用途,后面介绍。常用别名:IP、SP、LR、PC。
栈:
r13(SP)是栈指针。ARM中使用向下的满栈(full-descending),即SP始终指向最后一个已进入栈的数据,每次压栈时,SP自减需要的内存大小,然后将值存到SP新的位置。
SP的值应在栈的有效区间内,且mod 4 = 0。栈上有例程的调用帧结构。不要轻易地修改这个值。
子例程调用
ARM和Thumb指令集均有一个BL指令,它的操作是:将BL指令顺序下一条指令的地址(即返回地址)送入链接寄存器LR(r14),然后将调用的目的地址(即子例程地址)送入寄存器PC(r15)。
如果在Thumb中调用BL,则LR的第0位被设为1,否则被设为0。(因为指令地址要4字节对齐,因此LR的第0和1位都没有用。)
子例程返回很简单,将LR的值送入PC即可。
任何模拟上述过程的指令序列也会起到BL的效果,例如:mov LR, PC; BX r4。注意,任何时候读PC,得到的值是当前指令地址+8(why?请自己google)。
结果返回
不超过4字节的结果,一律用r0返回;
超过4字节的基本类型,继续用r1, r2, r3;
超过4字节的复合类型,或动态大小的结果,存储在内存中,并将其地址作为调用参数之一传入。
参数传递
使用r0 – r3传递参数,如果不够,使用栈。
语言中的数据类型会按照相关标准转化为机器数据类型。
Hi, I want to be a friend with you and I send an E-mail to you. Please check your gmail.