学习过程中的总结,有什么不对的地方望指出,谢谢~
Asm 语句允许直接在 C 代码中包含汇编指令。特别是对于代码的性能,或者访问 C 程序不易获得的汇编指令,这可以帮助我们最大限度地提高时间时间.
来看看下面的C代码,汇编语法一般情况下,第一个操作数是dst,就是下面我们看到的%1,是输出,%0是输入,也是source.
下面代码的意思就是:把src拷贝给dst,然后给dst加1. 所以如果你的cpu或者GPU支持这个指令,打印出来的结果就是2.
int src = 1;
int dst;
asm ("mov %1, %0\n"
"add $1, %0"
: "=r" (dst)
: "r" (src));
printf("%d\n", dst);
上面这个实例里面的r
的意思是register寄存器的意思,除了r还有其他关键字
- r 操作数指定一个通用的寄存器 register
- m 操作数指定一个内存地址 memory
- i 操作数指定一个整数常量 integer
- g 操作数必须是通用寄存器、内存地址或整数常量中的一个.也可以用
rmi
来表示
需要注意有简单的几点,可以下面的一个格式:
- 扩展的 asm 语句必须位于
函数内部
。只有基本的空间可以是函数之外的。 - 用 asm 关键字作为开头,也可以用__asm__,用前者的时候比较多
- optional stuff可以为空、volatile、goto其中一个
- assembler template 就是你想用的汇编指令
- 每一个asm块,长度不超过30个inputs
- 输出、输入、lable都是可选的
- 冒号只需要到您希望使用的参数为止,如果希望跳过参数,则冒号之间没有任何内容是有效的
语法格式:
asm <optional stuff> (
"assembler template"
: outputs
: inputs
: clobbers
: labels)
输入和输出
输出和输入是汇编程序模板“格式字符串”的参数。它们是以逗号分隔的。他们都使用以下两种模式中的一种:
"constraint" (expression)
[Name] "constraint" (expression)
限制
比如这个乘法指令imul %0, %1, %2
,按照上面提到的%0是dst,后面2个是src.
对于x86指令架构,乘法指令有三个操作数的时候:此种形式需要一个目标操作数%0(第一个操作数)与两个源操作数(第二个与第三个操作数)。这里,第一个
源操作数
%1(可以是通用寄存器或内存位置)乘以第二个源操作数%2(立即数)。乘积随后存储到目标操作数%0(通用寄存器)。
- 第一个%0 一定就是寄存器,不能是const
- 第二个操作数%1,可能是regist或者是memory地址
- 第三个操作数%2,一定就是const integer
(ARM 只支持寄存器上的运算,所以所有的操作数都是寄存器
操作数。)
输出
输出指定左值,结果应该存储在操作结束的位置。可赋值的通常是 lvalue (变量、取消引用的指针、数组下标、结构字段等)。只要遵守约束,大多数左值都被接受为操作数: 例如,可以使用 r (register)传递位字段,但不能使用 m (memory) ,因为不能获取位字段的地址。
- 输出的约束字符串必须以 = 或 + 作为前缀
+
表示输出实际上是一个读写值
。操作数最初具有表达式包含的值。可以在程序集字符串中的任何位置读取此输出操作数。=&
意味着输出是一个提前完成的输出。它的初始值未指定。一旦给 =& 操作数赋值,就不会出现从该操作数读取的错误。=
意味着输出是只写
的。=@ccCOND
是=
的特殊情况,它允许您在汇编语句的末尾查询条件代码的结果。不能在程序集模板中引用条件输出。
比如x86指令集是这样的
asm("addl %1, %0" : "+rm" (foo) : "g" (bar))
在arm就是下面这样的,arm只有寄存器
asm("add %0, %1, %2" : "=r" (foo) : "r" (foo), "r" (bar))
输入
输入可以是任何值,只要它对约束有意义。例如,要使用 i 约束,编译器必须能够发现该值是一个常量。它们没有任何前缀。
如果语法中使用了asm volatile
,代码有可能被优化掉,比如没有用到的无效语句.
还有其他的goto、labels等高级用法,可以在实战用多练习,这样更容易掌握,学习的新的只是用起来才是关键.
Read more
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
https://llvm.org/docs/LangRef.html#inline-assembler-expressions
https://www.felixcloutier.com/documents/gcc-asm.html
微信公众号:cdtfug, 欢迎关注一起吹牛逼,也可以加微信号「xiaorik」朋友圈围观。