ATPCS介绍
ATPCS(ARM-Thumb Produce Call Standard)是ARM程序和Thumb程序中子程序调用的基本规则,目的是为了使单独编译的C语言程序和汇编程序之间能够相互调用。这些基本规则包括子程序调用过程中寄存器的使用规则、数据栈的使用规则和参数的传递规则。
寄存器的使用规则
子程序间通过寄存器R0~R3来传递参数,这时,寄存器R0~R3可以记作A1~A4。被调用的子程序在返回前无需恢复寄存器R0~R3的内容;
在子程序中,使用寄存器R4~R11来保存局部变量。这时,寄存器 R4~R11可以记作V1~V8。如果在子程序中使用到了寄存器V1~V8中的某些寄存器,子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值;对于子程序中没有用到的寄存器则不必进行这些操作。在Thumb程序中,通常只能使用寄存器R4~R7来保存局部变量;
寄存器R12用作子程序间的scratch寄存器(用于保存SP,在函数返回时使用该寄存器出栈),记作ip(Intra-Procedure-call Scratch Register;内部程序调用暂存寄存器)。在子程序间的连接代码段中常有这种使用规则;
寄存器R13用作数据栈指针,记作sp。在子程序中寄存器R13不能用作其他用途。寄存器sp在进入子程序时的值和退出子程序时的值必须相等;
寄存器R14称为链接寄存器,记作lr。它用于保存子程序的返回地址。如果在子程序中保存了返回地址,寄存器R14则可以用作其他用途;
寄存器R15是程序计数器,记作pc。它不能用作其他用途。
ATPCS中各寄存器的使用规则及其名称
寄存器 | 别名 | 特殊名 | 使用规则 |
---|---|---|---|
R0 | a1 | 参数/结果/scratch寄存器1 | |
R1 | a2 | 参数/结果/scratch寄存器2 | |
R2 | a3 | 参数/结果/scratch寄存器3 | |
R3 | a4 | 参数/结果/scratch寄存器4 | |
R4 | v1 | ARM状态局部变量寄存器1 | |
R5 | v2 | ARM状态局部变量寄存器2 | |
R6 | v3 | ARM状态局部变量寄存器3 | |
R7 | v4 | wr | ARM状态局部变量寄存器4 Thumb状态工作寄存器 |
R8 | v5 | ARM状态局部变量寄存器5 | |
R9 | v6 | sb | ARM状态局部变量寄存器6, 在支持RWPI的ATPCS中为静态基址寄存器 |
R10 | v7 | sl | ARM状态局部变量寄存器7, 在支持数据栈检查的ATPCS中为数据栈限制指针 |
R11 | v8 | fp | ARM状态局部变量寄存器8/帧指针 |
R12 | ip | 子程序内部调用的scratch寄存器 | |
R13 | sp | 数据栈指针 | |
R14 | lr | 连接寄存器 | |
R15 | pc | 程序计数器 |
数据栈使用规则
满(FULL)栈
当堆栈指针指向栈顶元素,即指向最后一个入栈的数据元素时
空(EMPTY)栈
当堆栈指针指向与栈顶元素相邻的一个可用数据单元时
递减(DESCENDING)堆栈
当数据栈向内存地址减小的方向增长时
递增(ASCENDING)堆栈
当数据栈向内存地址增加的方向增长时,
- FD (Full Descending) 满递减
- ED (Empty Descending)空递减
- FA (Full Ascending) 满递增
- EA (Empty Ascending) 空递增
ATPCS规定数据栈为FD(满递减)类型。异常中断的处理程序可以使用中断程序的数据栈,但是要保证中断程序的数据栈足够大。
参数传递规则
参数个数固定的子程序参数传递规则
各个浮点参数按顺序处理;
为每个浮点参数分配FP寄存器。分配的方法是,满足该浮点参数需要的且编号最小的一组连续的FP寄存器。 第一个整数参数,通过寄存器R0~R3来传递。其他参数通过数据栈传递
参数个数可变的子程序参数传递规则
对于参数个数可变的子程序,当参数不超过4个时,可以使用寄存器R0~R3来传递参数;当参数超过4个时,还可以使用数据栈来传递参数;
在参数传递时,将所有参数看作是存放在连续的内存字单元中的字数据。然后,依次将各字数据传送到寄存器R0、Rl、R2、R3中,如果参数多于4个,将剩余的字数据传送到数据栈中,入栈的顺序与参数顺序相反,即最后一个字数据先入栈。
子程序结果返回规则
结果为一个32位的整数时,可以通过寄存器R0返回;
结果为一个64位整数时,可以通过寄存器R0和R1返回,依次类推;
结果为一个浮点数时,可以通过浮点运算部件的寄存器f0、d0或者s0来返回;
结果为复合型的浮点数(如复数)时,可以通过寄存器f0~fn或者d0~dn来返回。
对于位数更多的结果,需要通过内存来传递。
参考文献:
孟祥莲.嵌入式系统原理及应用教程(第2版)[M].北京:清华大学出版社,2017.