六、C与ARM汇编混合编程

时间:2022-01-05 01:05:43
     在应用程序设计中,如果所有任务均用汇编语言来完成,其工作量是可想而知的,而且不利于系统升级或应用软件移植。事实上, ARM体系结构支持C/C++与汇编语言混合编程 ,在一个完整的系统中,除了CPU初始化部分用汇编完成以外,其主要的编程任务一般都用C/C++完成。
     汇编语言与C/C++的混合编程通常有以下几种方式:
        1. 在C/C++程序中嵌入汇编指令。
        2. 在汇编程序中访问C/C++定义的全局变量。
        3. 在C/C++程序中调用汇编函数。
        4. 在汇编程序中调用C/C++函数。

1、C/C++嵌入汇编
在C/C++程序中使用内嵌的汇编指令的语法格式:
使用关键字 __asm 来标识一段汇编指令程序
__asm
{
汇编程序语言
……
汇编程序语言
}
练习示例:
#include <stdio.h>

void my_strcpy(const char *src, char *dest)

{
	char ch;
	__asm
	{
		loop:
   		ldrb ch, [src], #1
   		strb ch, [dest], #1
   		cmp ch, #0
   		bne loop
	}
}

int main()
{
	char *a = "forget it and move on!";
	char b[64];
	my_strcpy(a, b);
	printf("original: %s", a);
	printf("copyed: %s", b);
	return 0;
}
2、汇编访问C/C++变量
内嵌函数不用单独编辑汇编语言文件,比较简洁,但是有诸多限制,当汇编代码较多时一般放在单独的汇编文件中。这时就需要 在汇编和C之间进行一些数据的传递,最简单的办法就是使用全局变量
练习示例:

C代码:

#include <stdio.h>

int gVar_1 = 12;
extern asmDouble(void);
int main()
{
	printf("original value of gVar_1 is: %d", gVar_1);
	asmDouble();
	printf(" modified value of gVar_1 is: %d", gVar_1);
	return 0;
}
汇编代码:
AREA asmfile, CODE, READONLY

EXPORT asmDouble
IMPORT gVar_1
asmDouble
	ldr r0, =gVar_1
	ldr r1, [r0]
	mov r2, #2
	mul r3, r1, r2
	str r3, [r0]
	mov pc, lr
END
3、C/C++调用汇编函数
在C中调用汇编文件中的函数,要做的主要工作有两个,
一是在C中声明函数原型,并加 extern 关键字
二是在汇编中用 EXPORT 导出函数名 ,并用该函数名作为汇编代码段的标识,最后用 mov pc, lr 返回。
然后,就可以在C中使用该函数了。
练习示例:
C语言部分:
#include <stdio.h>

extern void asm_strcpy(const char *src, char *dest);

int main()
{    
	const char *s = "seasons in the sun";
	char d[32];
	asm_strcpy(s, d);
	printf("source: %s", s);
	printf("destination: %s",d);
	return 0;
}
汇编部分:
AREA asmfile, CODE, READONLY
EXPORT asm_strcpy
asm_strcpy
loop:
	ldrb r4, [r0], #1
	cmp r4, #0
	beq over
	strb r4, [r1], #1
	b loop

over:
	mov pc, lr
END
六、C与ARM汇编混合编程
4、汇编函数调用C/C++
在汇编中调用C的函数,需要在汇编中 IMPORT 对应的C函数名,然后将C的代码放在一个独立的C文件中进行编译。
练习示例:

汇编部分:

EXPORT asmfile
AREA asmfile, CODE, READONLY
IMPORT cFun 
ENTRY
	mov r0, #11
	mov r1, #22
	mov r2, #33 
	BL cFun
END
C语言部分:
int cFun(int a, int b, int c)
{
    return a + b + c;
}