本文共 1423 字,大约阅读时间需要 4 分钟。
虽然汇编语言编写繁琐,但执行效率高,能够更加直接地控制寄存器,因此有时在c语言中需要与汇编混合编程。
混合类型:1.汇编调用C函数:修改PC寄存器,使其指向C函数。如调用gboot_main
ldr pc, =gboot_main2.C调用汇编函数:直接在C语言中调用函数,但被调用的汇编函数若在其它文件里,需要先将该汇编函数设置为全局函数。如调用light_led函数
light_led();3.C内嵌汇编:C内嵌汇编以关键字”asm”或”asm”开始,下辖四个部分,各部分之间使用”:”分开,第一部分是必须写的,后面三部分是可以省略,但是分号:不能省略!其中破坏描述部分表示的是当汇编语言部分对某些寄存器的值进行了修改,则需要将这些寄存器的名字列到破坏描述部分。
__asm__( 汇编语句部分 :输出部分 :输入部分 :破坏描述部分);
1).汇编语句部分:汇编语句的集合,可以包含多条汇编语句,每条语句之间需要使用换行符 “\n”隔开或使用分号“ ; ”隔开。
2).输出部分:在汇编中被修改的C变量列表 3).输入部分:作为参数输入到汇编中的变量列表 4).破坏描述部分:执行汇编指令会破坏的寄存器描述例子:往协处理器CP15的c1写入数据
void write_p15_c1 (unsigned long value){__asm__( "mcr p15, 0, %0, c1 , c0, 0\n" : : "r"(value) @编译器选择一个R*寄存器 : "memory");}
其中%0表示的是0号参数,对应着“r”,而“r”的值来源于value。
从CP15的c1读出数据
unsigned long read_p15_c1 (void){unsigned long value;__asm__( "mrc p15, 0, %0, c1 , c0, 0\n" : "=r"(value) @ '=' 表示只写操作数,用于输出部 : : "memory");return value;}
其中%0表示的是0号参数,要写入r寄存器,而r寄存器的值再赋给value。
C内嵌汇编优化
unsigned long old;unsigned long temp;__asm__ volatile( "mrs %0, cpsr \n" "orr %1 , %0, #128 \n" "msr cpsr_c, %1\n" : "=r"(old), "=r"(temp) : :"memory");
使用volatile的作用是告诉编译器,不要对接下来的这部分代码进行优化。
在C嵌套汇编代码点亮led灯:
#define GPBCON 0x56000010#define GPBDAT 0x56000014int gboot_main(){ __asm__( "ldr r1,=0x15400\n" "str r1, [%0]\n" "ldr r1,=0x6BF\n" "str r1, [%1]\n" : :"r"(GPBCON),"r"(GPBDAT) :"r1" ); return 0; }