汇编和C的交叉访问也是很常见的,汇编中访问C,是因为一般上电初始化只能用汇编,但是汇编语言毕竟不是高级语言,想要简单实现复杂功能,就需要在汇编中调用C,而C中调用汇编,多是因为需要直接跟底层硬件打交道,所以需要C中引用汇编,简单的说几种:
一、汇编程序中访问C程序变量
(1)在汇编中,先使用IMPORT声明该变量。
(2)使用LDR指令读取该变量的内存地址,也就是用“LDR r0,=global1”
(3)根据数据类型,选择使用STR。
程序例程:
AREA globals,CODE,READONLY
EXPORT asmsub //声明该汇编函数可被外部使用
IMPORT globv1 //声明该变量是外部文件中定义的
asmsub
LDR r1,=globv1
LDR r0,[r1]
ADD r0,r0,#2
STR r0,[r1]
MOV pv,lr
END
二、C程序中调用汇编程序
使用关键字extern 声明要被调用的汇编程序,这一点跟嵌入式中extern之前的理解不太一样,其实也是一样的,只是之前在头文件中定义extern 声明时,理解的有些片面。之所以在头文件,然后再包含头文件,本身就是说明要想调用别的文件定义的函数,就需要用extern声明。
程序案例:
//C程序
#include
extern void strcopy(char *d,char *s); //用关键字extern声明
int main()
{
char *detstr,*srcstr;
.......
....
strcopy(detstr,srcstr);
}
;汇编程序
AREA SCopy,CODE,READONLY
EXPORT strcopy //要想被别人调用,必须要先用EXPORT声明
strcopy
LDRB r2,[r1],#1
STRB r2,[r0],#1
CMP r2,#0
BNE strcopy
MOV pc,lr
END
三、汇编程序调用C程序
汇编中调用C程序,有一个关键问题就是参数的传递,一般会默认R0存放第1个参数,R1存放第2个参数,R2存放第3个参数,R3存放第4个参数,第5个参数不是通过R5,而是利用数据栈传送,而且由于利用了数据栈传递参数,在程序调用结束后,还要调整数据栈指针。
程序实例:
//C程序 fun()返回5个整数的和
int func(int a, int b, int c, int d, int e)
{
return a + b + c + d +e;
}
;汇编程序调用C程序必须要使用IMPORT关键字声明
EXPORT f
AREA f,CODE,READONLY
IMPORT func ;声明该函数是外部定义
STR lr,[sp,#-4] ;栈是从高向低地址增长的,所以-4,保存返回地址
ADD r1,r0,r0
ADD r2,r1,r0
ADD r3,r1,r2
STR r3,[sp,#-4]
ADD r3,r1,r1
BL func ;注意这里是BL,而不是B,会自动保存lr
ADD sp,sp,#4 ;调整数据栈指针,准备返回
LDR pc,[sp],4 ;返回
END