汇编和C交叉调用

    汇编和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

    

你可能感兴趣的:(ARM)