ARM
一. C/C++程序中使用内嵌的汇编指令的语法格式
__asm
{
汇编语言程序
}
其中: 如果一行中有多个汇编指令,指令之间使用分号(;)分开,在一条指令占多行,使用续行符号(\)
例如:
int min(int x,int y);
int xmain(void)
{
int a = 3;
int b = 2;
int min_int = min(a,b);
return min_int;
}
__asm int min(int x,int y)
{
CMP R0,R1
MOVLT R0,R0
MOVGE R0,R1
BX LR
}
注意事项:
1. 必须小心使用物理寄存器, 如R0~R3,SP,LR和CPSR中的N,Z,C,V标志位.
因为计算汇编代码中的C表达式时, 可能会使用这些物理寄存器,并会修改N,Z,C,V标志位
__asm
{
MOV R0,X
ADD Y,R0,X/Y //计算x/y时,R0会被修改.
}
解决方法:
__asm
{
MOV var,x
ADD y,var,x/y
}
2. C程序中声明的全局变量可以被汇编程序通过地址间接访问.
方法如下:
(1)使用IMPORT伪指令声明这个全局变量.
(2)使用LDR指令读取该全局变量的内存地址,通常该全局变量的内存地址存放在程序的数据缓冲池中
(3)根据该数据类型,使用相应的LDR指令读取该全局变量的值,使用相应的STR指令修改该全局变量的值
例如:
AREA globals, CODE, READONLY
EXPORT asmsub
IMPORT glovbvar ;声明外部变量glovbvar
asmsub
LDR R1,=glovbvar ;装载变量地址
LDR R0,[R1] ;读出数据
ADD R0,R0,#1 ;加1操作
STR R0,[R1] ;保存变量值
MOV PC,LR
END
3.ASM和C混合的调用
(1)数据栈的使用规则, ATPCS规定数据栈为FD(满递减)类型,并且对数据栈的操作是8位字节对齐.
如果要进行出栈和入栈操作,则必须使用ldmfd和stmfd指令
(2)参数的传递规则
参数不超过4个时, 可以使用寄存器R0~R3来传递参数,当参数超过4个时,还可以使用数据栈.
结果为一个32位整数时,可以通过寄存器R0返回.
结果为一个64位整数时,可以通过寄存器R0和R1返回,依此类推
4.C程序调用汇编程序
(1)汇编程序的设置要遵循ATPCS规则, 保证程序调用时参数的正确传递.
(2)在汇编程序中使用EXPORT伪指令声明本子程序,使其它程序可以调用此子程序
(3)在C语言程序中使用extern关键字声明外部函数(声明要调用的汇编子程序),
即可调用此汇编子程序

5.汇编程序调用C程序
(1)汇编程序的设置要遵循ATPCS规则,保证程序调用时参数的正确传递.
(2)在汇编程序中使用IMPORT伪指令声明将要调用的C程序函数.
(3)在调用C程序时,要正确设置入口参数,然后使用BL调用.
例子:
C函数:int sum5(int a,int b,int c,int d,int e)
{ return (a+b+c+d+e); }
汇编程序:
AREA sample,CODE,READONLY
IMPORT sum5
CALLSUM
STMFD sp!,{LR}; lr寄存器放栈.
ADD R1,R0,R0 ;设置sum5函数入口参数,R0为参数a
ADD R2,R1,R0 ;R1为参数b,R2为参数c
ADD R3,R1,R2 ;
STR R3,R1,R2,STR R3,[sp,#-4]! ;参数e要通过堆栈传递
ADD R3,R1,R1 ;R3为参数d
BL sum5
ADD sp, sp#4 ;修正sp指针
LDMFD sp,pc ;子程序返回
END