ATPCS即ARM-THUMB procedure call standard的简称。
PCS规定了应用程序的函数可以如何分开地写,分开地编译,最后将它们连接在一起,所以它实际上定义了一套有关过程(函数)调用者与被调用者之间的协议。
PCS强制实现如下约定:调用函数如何传递参数(即压栈方法,以何种方式存放参数),
被调用函数如何获取参数,以何种方式传递函数返回值。
PCS的制订是一系列指标的“tradeoff(折衷)”(因为很大程度上涉及系统的一些性能),如会涉及生成代码的大小,调试功能的支持,
函数调用上下文处理速度以及内存消耗。当然,通过
编译器的支持可以让生成的代码有不同的特性,如gcc编译选项可以支持或不支持framepointer来支持深入调试功能或提高程序运行性能。
PCS是与体系结构密切相关的,直接涉及
编译器如何使用处理器提供的应用
寄存器,如编译器使用什么寄存器作为栈
指针,利用哪些寄存器作直接传参等。值得注意的是,没有谁规定说PCS是必须这样而不是那样的。它是应用相关的。任何一个操作系统和应用可以处于它自身的考虑定义自己的PCS。当然,如果那样,也必须有自己的
编译器。而实际上,在一个处理器设计时,都会有某种假设,所以PCS某种程度上应该是一样的。
ATPCS就是基于ARM指令集和THUMB指令集过程调用的规范。
一.ATPCS概述...
ATPCS规定了一些
子程序之间调用的基本规则.这些基本规则包括
子程序调用过程中寄存器的使用规则,
数据栈的使用规则,
参数的传递规则.为适应一些特定的需要,对这些基本的调用规则进行一些修改得到几种不同的子程序调用规则,这些特定的调用规则包括:
支持数据栈限制检查的ATPCS.
支持只读段位置无关的ATPCS.
支持可读写段位置无关的ATPCS.
支持ARM程序和THUMB程序混合使用的ATPCS.
处理浮点运算的ATPCS...
有调用关系的所有
子程序必须遵守同一种ATPCS.
编译器或者
汇编器在ELF格式的目标文件中设置相应的属性,标识用户选定的ATPCS类型.对应不同类型的ATPCS规则,有相应的C语言库,连接器根据用户指定的ATPCS类型连接相应的C语言库...
使用ADS的C语言
编译器编译的C语言
子程序满足用户指定的ATPCS类型. 而对于
汇编语言程序来说,完全要依赖用户来保证各子程序满足选定的ATPCS类型. 具体来说,汇编语言子程序必须满足下面三个条件: 在子程序编写时必须遵守相应的ATPCS规则; 数据栈的使用要遵守ATPCS规则; 在汇编编译器中使用-apcs选项...
二. 基本ATPCS...
基本ATPCS规定了在
子程序调用时的一些基本规则,包括以下三个方面的内容:
各寄存器的使用规则及其相应的名字;
数据栈的使用规则;
参数传递的规则. 相对于其他类型的ATPCS,满足基本ATPCS的程序的执行速度更快,所占用的内存更少. 但是它不能提供以下的支持: ARM程序和THUMB程序相互调用; 数据以及代码的位置无关的支持; 子程序的可重入性; 数据栈检查的支持. 而派生的其他几种特定的ATPCS就是在基本ATPCS的基础上再添加其他的规则而形成的.其目的就是提供上述的功能...
寄存器的使用规则:
2.
在子程序中,使用R4~R11来保存局部变量.这时
寄存器R4~R11可以记作: V1~V8 .如果在子程序中使用到V1~V8的某些寄存器,
子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值,对于子程序中没有用到的寄存器则不必执行这些操作.在THUMB程序中,通常只能使用寄存器R4~R7来保存局部变量.
5. 寄存器R14用作连接寄存器,记作lr ; 它用于保存
子程序的返回地址,如果在子程序中保存了返回地址,则R14可用作其它的用途.
参数的传递规则.
对于参数个数可变的
子程序,当参数不超过4个时,可以使用
寄存器R0~R3来进行
参数传递,
当参数超过4个时,还可以使用数据栈来传递参数. 在
参数传递时,将所有参数看做是存放在连续的内存单元中的字数据。然后,依次将各名字
数据传送到
寄存器R0,R1,R2,R3; 如果参数多于4个,将剩余的字数据传送到数据栈中,入栈的顺序与参数顺序相反,即最后一个字数据先入栈. 按照上面的规则,一个浮点数参数可以通过寄存器传递,也可以通过数据栈传递,也可能一半通过寄存器传递,另一半通过数据栈传递.
2.参数个数固定的
子程序参数传递规则
对于参数个数固定的
子程序,参数传递与参数个数可变的子程序参数传递规则不同,如果系统包含
浮点运算的硬件部件,浮点参数将按照下面的规则传递: 各个浮点参数按顺序处理;为每个浮点参数分配FP
寄存器;分配的方法是,满足该浮点参数需要的且编号最小的一组连续的FP寄存器.第一个整数参数通过寄存器R0~R3来传递,其他参数通过数据栈传递.
子程序结果返回规则
1.结果为一个32位的整数时,可以通过
寄存器R0返回.
2.结果为一个64位整数时,可以通过R0和R1返回,依此类推.