4.2.2 C语言中内嵌汇编代码
在C程序中内嵌的汇编代码指令支持大部分的ARM和Thumb指令,不过其使用与汇编文件中的指令有些不同,主要存在以下几个方面的限制。
在使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突。
不能直接向PC寄存器赋值,程序跳转要使用B或者BL指令。
R12和R13可能被编译器用来存放中间编译结果,计算表达式值时又能将R0到R3, R12及R14用于子程序调用,因此要避免直接使用这些物理寄存器。
一般不要直接指定物理寄存器,而是让编译器进行分配。
ARM汇编和C混合编程最简单的方法就是内联汇编(Inline Assemble)和嵌入式汇编(Embedded Assemble)。
内联汇编是指在C函数定义中使用__asm或者asm的方法,用法如下:
- __asm
- {
- instruction[; instruction]
- … …
- [instruction]
- }
或者
- asm("instruction[; instruction]");
下面给出一个具体的示例用法:
- #include<stdio.h>
- void my_story(const char *src,char *dest) ;函
数定义,参数为一个常量字符指针src和一 - ;个变量字
符指针dest,功能将src复制到dest - {
- char ch; ;定义一个字符变量
- __asm ;内嵌汇编代码标识
- {
- loop: ;循环体
- ldrb ch,[src],#1 ;ch=[src+1]
- strb ch,[dest],#1 ;[dest+1]=ch
- cmp ch,#0 ;判断
字符串是否结束,结束ch=0 - bne loop ;不为0,
则跳转到loop继续循环 - }
- }
- int main() ;主函数
- {
- char *a="hello,arm"; ;定义
字符串常量a="hello,arm" - char b[64]; ;定义字符串变量
- my_strcpy(a,b); ;调用my_strcpy函数
- printf("original:%s",a); ;输出结果
- printf("copyed:%s",b);
- return 0; ;返回
- }
内联汇编的用法跟真实汇编之间有很大的区别,并且不支持Thumb。与内联汇编不同,嵌入式汇编具有真实汇编的所有特性,同时支持ARM和Thumb,但是不能直接引用C语言的变量定义,数据交换必须通过ATPCS进行。嵌入式汇编在形式上表现为独立定义的函数体,如下所示。
- _asm int add(int i,int j) //定义嵌入式汇编
- {
- ADD R0,R0,R1 //R0R0=R0+R1
- MOV PC,LR
- }
- void main()
- {
- printf("12345+6789=%d\n",add(12345,6789));
- }
灵活使用内联汇编和嵌入式汇编,可以提高程序的效率。