第六章 ATPCS介绍
在汇编编译器中使用-apcs选项。
6.1.2寄存器使用规则
子程序使用R0~R3来传递参数。用R4~R11来保存局部变量,thumb使用R4~R7。R12记作IP,调用scratch寄存器。R13记作SP,用作数据堆栈指针。R14记作LR,用作保存子程序的返回地址。R15记作PC,是程序计数器。
6.1.3数据栈使用规则
有四种堆栈方向:
FD、FA、ED、EA
ATPCS规定使用FD
6.1.4参数传递规则
1、参数可变:参数不超过4,使用R0~R3,超过则将多的参数送到数据栈中保存
2、参数固定:第一个参数,通过R0~R3,其他参数使用数据栈。
3、结果返回:结果为32位整数,使用R0;结果为64位,使用R0和R1;结果为浮点,使用f0、d0或者s0;
第七章 ARM和Thumb混合编程
状态切换指令:
BLX 、BX 目标地址
LDR、LDM及POP 向PC寄存器赋值
AREA AddReg ,CODE ,READONLY
ENTRY
main
ADR R0,ThumbProg+1 ;存储单元的地址肯定是偶数,也就是最低位肯定是0,但ARM与thumb之间的切换是
;通过Rn的最低位来判断的,1为thumb,0为ARM
BX R0 ;跳转到ThumbPro,并且程序切换到Thumb状态
CODE16
ThumbProg
MOV R2,#2
MOV R3,#3
ADD R2,R2,R3
ADR R0,ARMProg
BX R0 ;跳转到ARMProg,并且切换到ARM状态
CODE32
ARMProg
MOV R4,#4
MOV R5,#5
ADD R4,R4,R5
stop
MOV R0,#0X18
LDR R1,=0X20026
SWI 0X123456
END
//C程序调用汇编程序
#include <stdio.h>
extern void strcopy(char *d,const char *s) ; //使用关键字extern声明外部函数,即调用的汇编程序
int main(void)
{
const char *srcstr="Source string";
char dststr[]="Destination string";
printf("Before copying :/n");
printf("%s/n %s/n",srcstr,dststr);
strcopy(dststr,srcstr);
printf("After copying :/n");
printf("%s/n %s/n",srcstr,dststr);
return 0;
}
;汇编程序
AREA STRCOPY ,CODE,READONLY
EXPORT strcopy //使用EXPORT伪操作声明汇编程序
strcopy
LDRB R2,[R1],#1 //寄存器R1中存放第srcstr地址
STRB R2,[R0],#1
CMP R2,#0
BNE strcopy
MOV PC,LR
END
;汇编程序调用C程序
int sum(int a,int b,int c,int d, int e)
{
return a+b+c+d+e;
}
EXPORT CALLSUM
AREA F ,CODE ,READONLY
IMPORT sum ;使用IMPORT 声明C程序sum()
CALLSUM
STR LR,SP! ;保存返回地址
ADD R1, R0,R0 ;假设进入程序时R0=I,设R1=2I
ADD R2,R1,R0
ADD R3,R1,R2
STR R3,[SP,#-4] ! ;第五个参数通过数据栈传递
ADD R3,R1,R1
BL sum
ADD SP,SP,#4 ;调整数据栈指针,准备返回
LDR PC,[SP],#4 ;返回
END