KG—ARM-Thumb子程序调用规则—ATPCS

来源:互联网 发布:ubuntu卸载qq国际版 编辑:程序博客网 时间:2024/04/30 11:47

为了使C语言程序和汇编程序之间能够互相调用,必须为子程序间的调用制定规则~~

然后呢,在ARM处理器中,这个规则被称为ATPCS:ARM程序和Thumb程序中子程序调用的规则(如果用过51单片机汇编和C的混合编程,那这个就So Easy了~~)。

这里只是说说基本的ATPCS规则包括寄存器使用规则、数据栈使用规则、参数传递规则。

1、寄存器使用规则:

ARM处理器中有r0-r15共16个寄存器,它们的用途是有一些约定的习惯的!

并依据这些用途定义了别名。

如图:

KG鈥擜RM-Thumb子程序调用规则鈥擜TPCS

寄存器的使用情况如下:

1)子程序间通过寄存器r0-r3来传递参数,这时可以使用它们的别名a0-a3,被调用的子程序返回前无需回复r0-r3的内容。

2)在子程序中,使用r4-r11来保存局部变量,这时可以使用它们的别名v1-v8,如果在子程序中使用了它们的某些寄存器,子程序进入时要保存这些寄存器的值,返回时再次恢复它们;

对于子程序中没有使用到的寄存器,则不必进行这些操作,在Thumb指令中,通常只能使用寄存器r4-r7来保存局部变量。

3)寄存器r12用作子程序间scratch寄存器,别名为ip。

4)寄存器r13用作数据栈指针,别名为sp,在子程序中寄存器r13不能用作它用,它的值在进入、退出子程序时必须相等。

5)寄存器r14称为连接寄存器,别名为lr,它用于保存子程序的返回地址。

如果在子程序中保存了返回地址(比如将lr值保存到数据栈中),r14可用作它用。

6)寄存器r15是程序计数器,别名pc,没有别的用途~~

2、数据栈使用规则

数据栈有两个增长方向;向内存地址减小的方向增长时,称为DESCENDING栈;

向内存地址增加的方向增长时,称为ASCENDING栈。

 

所谓数据栈的增长就是移动栈指针。当栈指针指向栈顶元素(最后一个入栈的数据)时,称为FULL栈;

当栈指针指向栈顶元素相邻的一个空的数据单元时,称为EMPTY栈。

 

综合这两个特点,数据栈可以分为以下4种:

1)FD: Full Descending,满递减。

2)ED:Empty Descending,空递减。

3)FA:Full Ascending,满递增。

4)EA:Empty Ascending,满递增。

 

ATPCS规定数据栈为FD类型,并且对数据栈的操作是8字节对齐的。使用stmdb/ldmia批量内存访问指令来操作FD数据栈。

使用stmdb命令往数据栈中保存内容时,先递减sp指针,再保存数据,

使用ldmia命令从数据栈中恢复命令时,先获得数据,再递增sp指针,sp指针总是指向栈顶元素,这刚好是FD栈的定义。

3、参数传递规则

一般来说,当参数个数不超过4个时,使用r0-r3这4个寄存器来传递参数;如果参数个数超过4个,剩余的参数通过数据栈来传递。

同样,对于一般的返回结果,通产使用a0-a3来传递。

 

例程:

假设CopyCode2SDRAM函数使用C语言实现的,数据原型为:

int CopyCode2SDRAM(unsigned char *buf,unsigned long StartAddr,int size)

在汇编代码中,使用下面的代码调用,同时判断返回值:

ldr r0,=0x30000000     @ 1、目标地址=0x30000000,这是SDRAM的起始地址

mov r1,#0              @ 2、源地址=0

mov r2,#16*1024        @ 3、复制长度=16K

bl  CopyCode2SDRAM     @ 4、调用C函数CopyCode2SDRAM

cmp a0,#0              @ 5、进行判断