内联汇编

asm asm-qualifiers ( AssemblerTemplate
: OutputOperands
[ : InputOperands
[ : Clobbers ] ])

内联汇编允许我们在C或C++代码中插入汇编语句,本文将对内联汇编的相关使用方法进行总结。

基本汇编——不带有运算数

基本语法

一个基本内联汇编语句语法如下:

1
asm [qualifiers] ( instructions )

修饰定语(Qualifiers)

修饰定语可添加inline,那么asm的语句将被优化,尽可能占用少的空间

参数

asm的参数为汇编语句,需要采用””括起来,并使用\n\t换行

例子

1
2
3
4
5
6
7
asm (".globl func\n\t"
".type func, @function\n\t"
"func:\n\t"
".cfi_startproc\n\t"
"movl $7, %eax\n\t"
"ret\n\t"
".cfi_endproc");

扩展汇编

语法

相比基本汇编,扩展汇编更加灵活高效,但是必须放在函数中。扩展汇编的基本语法如下:

1
2
3
4
5
asm ( assembler template 
: output operands /* optional 输出操作数*/
: input operands /* optional 输入操作数*/
: list of clobbered registers /* optional 破坏的寄存器*/
);

assembler template

assembler template由汇编指令组成

输入/输出操作数

操作数顺序

我们在内联汇编中能看到%0, %1, %2...,这些数表示输入的第1个、第2个、…、第n个操作数,顺序即输入操作数在内联汇编中的排列顺序。

操作数限制

我们可以用限制词限制输入输出操作数的位置,限制词的语法为:

  • : "=c" (output)
  • : "c" (input)

常用的限制词如下:

  • r:表示使用任意寄存器保存操作数

例子2

1
2
3
4
5
6
7
int a=10, b;
asm ("movl %1, %%eax;
movl %%eax, %0;"
:"=r"(b) /* output */
:"r"(a) /* input */
:"%eax" /* clobbered register */
);

这段代码解释如下:

  • b是输出操作数,由%0表示第一个传入的表示输入或输出操作数的变量
  • a是输入操作数,由%1表示第二个传入的表示输入或输出操作数的变量
  • r为操作数限制,表示使用任意寄存器保存操作数
  • 寄存器前有两个%%,这是为了区分操作数和寄存器,操作数只有一个%
  • 被破坏的寄存器是%eax,告知GCCeax的值发生了改变,GCC将不会用这些寄存器保存值

当上面的代码运行完成后,b将保存更新后的输出值。

参考文献

0%