在应用程序设计中,如果所有任务均用汇编语言来完成,其工作量是可想而知的,而且不利于系统升级或应用软件移植。事实上,
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
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; }