寄存器的使用规则:
寄存器 R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15
ATPCS名称 a1 a2 a3 a4 v1 v2 v3 v4 WR v5 v6 SB v7 SL v8 FP
IP SP LR PC 1.子程序间经过寄存器R0~R3来传递参数。被调用的子程序在返回前无须恢复寄存器R0~R3的内容。
2.在子程序中,使用寄存器R4~R11来保存局部变量。这时,寄存器R4~R11能够记为v1~v8。若是在子程序中使用了寄存器v1~v8中的某些寄存器,则子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值。在Thumb程序中,一般只能使用寄存器R4~R7来保存局部变量。另外R9,R10和R11还有一个特殊做用,分别记为:静态基址寄存器SB,数据栈限制指针SL和桢指针FP。
3.寄存器R12用作过程调用中间临时寄存器IP。寄存器R13用作堆栈指针SP。在子程序中寄存器R13不能用作其它用途。寄存器SP在进入子程序时的值和退出子程序的值必须相等。寄存器R14称为连接寄存器LR,它用于保存子程序的返回地址。若是在子程序中保存了返回地址,寄存器R14则能够用作其余用途。寄存器R15为程序计数器PC,不能用作其余用途。
4.只有寄存器R0~R7,SP,LR和PC能够在Thumb状态下使用,其中R7经常做为Thumb状态的工做寄存器,记为WR。
PCS即Procedure Call Standard(过程调用规范),ATPCS即ARM-THUMB procedure call standard。
PCS规定了应用程序的函数能够如何分开地写,分开地编译,最后将它们链接在一块儿,因此它实际上定义了一套有关过程(函数)调用者与被调用者之间的协议。PCS强制实现以下约定:调用函数如何传递参数(即压栈方法,以何种方式存放参数),被调用函数如何获取参数,以何种方式传递函数返回值。PCS的制订是一系列指标的“tradeoff(折衷)”(由于很大程度上涉及系统的一些性能),如会涉及生成代码的大小,调试功能的支持,函数调用上下文处理速度以及内存消耗。固然,经过编译器的支持可让生成的代码有不一样的特性,如gcc编译选项能够支持或不支持framepointer来支持深刻调试功能或提升程序运行性能。PCS是体系结构密切相关的,直接涉及编译器如何使用处理器提供的应用寄存器,如编译器使用什么寄存器做为栈指针,利用哪些寄存器做直接传参等。值得注意的是,没有谁规定说PCS是必须这样而不是那样的。它是应用相关的。任何一个操做系统和应用能够处于它自身的考虑定义本身的PCS。固然,若是那样,也必须有本身的编译器。而实际上,在一个处理器设计时,都会有某种假设,因此PCS某种程度上应该是同样的。
寄存器的使用规则:
1. 子程序经过寄存器R0~R3来传递参数. 这时寄存器能够记做: A0~A3 , 被调用的子程序在返回前无需恢复寄存器R0~R3的内容.
2. 在子程序中,使用R4~R11来保存局部变量,这时寄存器R4~R11能够记做: V1~V8 .若是在子程序中使用到V1~V8的某些寄存器,子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值,对于子程序中没有用到的寄存器则没必要执行这些操做.在THUMB程序中,一般只能使用寄存器R4~R7来保存局部变量.
3.寄存器R12用做子程序间scratch寄存器,记做ip; 在子程序的链接代码段中常常会有这种使用规则.
4. 寄存器R13用做数据栈指针,记作SP,在子程序中寄存器R13不能用作其余用途. 寄存器SP在进入子程序时的值和退出子程序时的值必须相等.
5. 寄存器R14用做链接寄存器,记做lr ; 它用于保存子程序的返回地址,若是在子程序中保存了返回地址,则R14可用做其它的用途.
6. 寄存器R15是程序计数器,记做PC ; 它不能用做其余用途.
7. ATPCS中的各寄存器在ARM编译器和汇编器中都是预约义的.
数据栈的使用规则
栈指针一般能够指向不一样的位置.当栈指针指向栈顶元素(即最后一个入栈的数据元素)时,称为FULL栈.当栈指针指向与栈顶元素相邻的一个元素时,称为Empty栈. 数据栈的增加方向也能够不一样. 当数据栈向内存减少的地址方向增加时,称为Descending栈; 当数据栈向着内存地址增长的方向增加时,称为Ascending栈. 综合这两种特色能够由如下4种数据栈: FD ED FA EA . ATPCS规定数据栈为FD类型,并对数据栈的操做是8字节对齐的,下面是一个数据栈的示例及相关的名词.
1.数据栈栈指针.stack pointer 指向最后一个写入栈的数据的内存地址.
2.数据栈的基地址.stack base 是指数据栈的最高地址.因为ATPCS中的数据栈是FD类型的,实际上数据栈中最先入栈数据占据的内存单元是基地址的下一个内存单元.
3.数据栈界限.stack limit 是指数据栈中可使用的最低的内存单元地址.
4.已占用的数据栈.used stack 是指数据栈的基地址和数据栈栈指针之间的区域.其中包括数据栈栈指针对应的内存单元.
5.数据栈中的数据帧(stack frames) 是指在数据栈中,为子程序分配的用来保存寄存器和局部变量的区域.
异常中断的处理程序可使用被中断程序的数据栈,这时用户要保证中断的程序数据栈足够大. 使用ADS编译器产生的目标代码中包含了DRFAT2格式的数据帧.在调试过程当中,调试器可使用这些数据帧来查看数据栈中的相关信息.而对于汇编语言来讲,用户必须使用FRAME伪操做来描述数据栈中的数据帧.ARM汇编器根据这些伪操做在目标文件中产生相应的DRFAT2格式的数据帧.
在ARMv5TE中,批量传送指令LDRD/STRD要求数据栈是8字节对齐的,以提升数据的传送速度.用ADS编译器产生的目标文件中,外部接口的数据栈都是8字节对齐的,而且编译器将告诉链接器: 本目标文件中的数据栈是8字节对齐的. 而对于汇编程序来讲,若是目标文件中包含了外部调用,则必须知足如下条件: 外部接口的数据栈必定是8位对齐的,也就是要保证在进入该汇编代码后,直到该汇编程序调用外部代码之间,数据栈的栈指针变化为偶数个字; 在汇编程序中使用PRESERVE8伪操做告诉链接器,本汇编程序是8字节对齐的.
参数的传递规则.
根据参数个数是否固定,能够将子程序分为参数个数固定的子程序和参数个数可变的子程序.这两种子程序的参数传递规则是不一样的.
1.参数个数可变的子程序参数传递规则
对于参数个数可变的子程序,当参数不超过4个时,可使用寄存器R0~R3来进行参数传递,当参数超过4个时,还可使用数据栈来传递参数. 在参数传递时,将全部参数看作是存放在连续的内存单元中的字数据。而后,依次将各名字数据传送到寄存器R0,R1,R2,R3; 若是参数多于4个,将剩余的字数据传送到数据栈中,入栈的顺序与参数顺序相反,即最后一个字数据先入栈. 按照上面的规则,一个浮点数参数能够经过寄存器传递,也能够经过数据栈传递,也可能一半经过寄存器传递,另外一半经过数据栈传递.
2.参数个数固定的子程序参数传递规则
对于参数个数固定的子程序,参数传递与参数个数可变的子程序参数传递规则不一样,若是系统包含浮点运算的硬件部件,浮点参数将按照下面的规则传递: 各个浮点参数按顺序处理;为每一个浮点参数分配FP寄存器;分配的方法是,知足该浮点参数须要的且编号最小的一组连续的FP寄存器.第一个整数参数经过寄存器R0~R3来传递,其余参数经过数据栈传递.
子程序结果返回规则
1.结果为一个32位的整数时,能够经过寄存器R0返回.
2.结果为一个64位整数时,能够经过R0和R1返回,依此类推.
3.结果为一个浮点数时,能够经过浮点运算部件的寄存器f0,d0或者s0来返回.
4.结果为一个复合的浮点数时,能够经过寄存器f0-fN或者d0~dN来返回.
5.对于位数更多的结果,须要经过调用内存来传递.
三.几种特定的ATPCS...
A.支持数据栈限制检查的ATPCS.
若是在程序设计期间可以准确地计算出程序所需的内存总量,就不须要进行数据栈的检查,可是在一般状况下这是很难作到的,这时须要进行数据栈的检查. 在进行数据栈的检查时,使用寄存器R10做为数据栈限制指针,这时寄存器R10又记做sl.用户在程序中不能控制该寄存器.具体来讲,支持数据栈限制的ATPCS要知足下面的规则: 在已经占有的栈的最低地址和sl之间必须有256字节的空间,也就是说,sl所指的内存地址必须比已经占用的栈的最低地址低256个字节.当中断处理程序可使用用户的数据栈时,在已经占用的栈的最低地址和sl之间除了必须保留的256个字节的内存单元外,还必须为中断处理预留足够的内存空间; 用户在程序中不能修改sl的值;数据栈栈指针sp的值必须不小于sl的值.
与支持数据栈限制检查的ATPCS相关的编译/汇编选项有下面几种: 选项/SWST 指示编译器生成的代码遵照支持数据栈限制检查的ATPCS,用户在程序设计期间不可以准确计算程序所需的数据栈大小时,须要指定该选项;选项/noswst指示编译器生成的代码不支持数据栈限制检查的功能,用户在程序设计期间可以准确计算出程序所需的数据栈大小,能够指定该选项,这个选项是默认的;选项/SWSTNA 若是汇编程序对因而否进行数据栈检查无所谓,而与该汇编程序链接的其余程序指定了选项swst/noswst,这时使用该选项.
编写遵照支持数据栈限制检查的ATPCS的汇编语言程序.
对于C程序和C++程序来讲,若是在编译时指定了选项SWST,生成的目标代码将遵照支持数据栈限制检查的ATPCS. 对于汇编语言程序来讲,若是要遵照支持数据栈限制检查的ATPCS,用户在编写程序时必须知足支持数据栈限制检查的ATPCS所要求的规则,而后指定选项SWST,下面介绍用户编写汇编语言程序时的一些要求.
叶子子程序是指不调用别的程序的子程序.
数据栈小于256字节的叶子子程序不准要进行数据栈检查,若是几个子程序组合起来构成的叶子子程序数据栈也小于256字节,这个规则一样适用; 数据栈小于256字节的非叶子子程序可使用下面的代码段来进行数据栈检查.编程