为什么要使用内嵌汇编?
内嵌汇编通常用于在程序中实现一些高效、精确的操作。例如,在嵌入式平台上运行的程序,如果需要代码占用内存更小、程序运行的效率更高或需要准确地操作寄存器时,嵌入汇编会是不错的选择。
基本语法
1 | asm("assembly code" /* 汇编代码 */ |
被改变的操作对象列表
在被改变的参数列表 clobbered_operand 中有一个比较有用的标识符:memory。指定 memory,相当于对编译器形成了一个内存读写的屏障,保证在内联汇编执行前,编译器将某些寄存器里的值刷新进内存,同时在内联汇编执行后,编译器重新加载相关变量的值。
所以我们可以见到这样的代码:
1 | asm volatile ("" ::: "memory"); |
作为内存屏障,保证编译器的优化不会跨过这道屏障。加上 volatile 告诉编译器不要优化汇编。
修饰符
修饰符一般跟在参数列表前面。
修饰符 | 含义 |
---|---|
= | 只写,常用于修饰所有输出操作数 |
无 | 只读 |
+ | 可读可写 |
r | 可以是任意通用寄存器存储其值 |
m | 一个有效的内存地址 |
i | 是立即数 |
% | 被修饰的操作数可以和下一个互换 |
& | 只能做输出,一般和 “=” 一起使用,如 “=&r(val)” |
x | 只能做输入 |
占位符
%0 表示输入和输出列表合并的第 1 个操作数,%1 表示第 2 个,以此类推。