C语言即可以实现高级语言的模块化编程,又可以实现很多底层操作。但是与汇编语言相比,C语言的效率毕竟还是无法媲美的。因此在对效率和硬件操作比较高的地方,可以采用将部分汇编语句嵌入到C语言中的方式来进行。
gcc的内联汇编语言提供了一种在C语言源程序中直接嵌入汇编指令的方法。既能够直接控制所形成的指令序列,又有着与C语言的良好接口。
ARM体系结构下的内联汇编 __asm__
用法格式
- __asm__ (汇编语句模板:输出部分:输入部分:破环描述部分)。// asm的四个部分用:隔开就算空着也要:隔开。例如 asm(:::破坏描述)。
- __asm__ 是gcc关键字asm的宏定义。
- 用asm或__asm__来声明一个内联汇编表达式。
- 任何内联汇编表达式都是以asm或__asm__开头的。
#define __asm__ asm
#define __volatile__ volatile
asm volatile("":::"memory");
- 有时需要在asm后面使用volatile。
- volatile是可选的,若有它则表示向gcc声明不允许对该内联汇编代码进行优化。否则当使用了优化选项gcc -o 进行编译时,gcc将会根据自己的判断决定是否对这个内联汇编表达式中的指令进行优化。
汇编语句模板
- 由汇编语句序列组成。
- 可以是空的,只不过没有实际意义。例如(__asm__ __volatile__(""))
- 但并非所有空语句都是没有意义的。
asm volatile("":::"memory")
这条语句向gcc声明“内存做了改动”。 - 每条指令都必须用 “” 括起来。
- 两条指令之间必须使用换行符或封号隔开。
- 指令中的操作数可以使用占位符引用C语言变量,操作占位符最多10个。%0,%1…%9
// 在ARM系统结构上关闭中断的操作。
int disable_interrupts(void){
unsigned long old, temp;
__asm__ __volatile__("mrs %0, cpsr\n"
"orr %1, %0, #0x80\n"
"msr cpsr_c, %1"
: "=r"(old), "=r"(temp)
:
:"memory");
return (old & 0x80) == 0;
}
输出部分
- 用来指定当前内联汇编语句的输出。
输入部分
- 用来指定当前内联汇编语句的输入。
破坏描述部分
- 通知gcc当前内联汇编语句可能会对某些寄存器或内存进行修改。
volatile关键字
- 表示某个变量的值随时可能被外部改变。编译器看到该类变量则会在每次使用前都去访问最新数据。(线程安全)