asm qualifiers (
assembler template
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
: GotoLabels
);
qualifiers:
assembler template:
assemblet template部分写汇编指令,通过\n\t分割每一条指令、对于寄存器的引用需要通过%%来引用,对于输入输出操作数则通过%1、%2这样的形式来引用,输入个输出会按照顺序编号。当没有任何输入输出和clobbered的时候,可以直接使用%来引用寄存器。
asm ("movl %eax, %ebx \\n\\t"
"movl $56, %esi \\n\\t"
"movl %ecx, $label(%edx,%ebx,$4) \\n\\t"
"movb %ah, (%ebx) \\n\\t");
输出操作数部分格式为:
[[asmSymbolicName]] constraint (cvariablename)
可以给输出操作数一个名字asmSymbolicName,否则就按照出现的顺序通过序号来引用,%0就是第一个输出操作数。constraint部分需要以=和+开头,+表示读写,=表示只写。比如=a,表示先将结果输出到rax/eax寄存器,然后再由rax/eax寄存器更新对应的输出变量。最后的cvariablename就是对应到代码中的变量名了。
输入操作数:
[[asmSymbolicName]] constraint (cexpression)
asmSymbolicName和输出操作数部分一致,输出和输入操作数是统一编号的,加入输出操作数有2个,那么输入操作数就要从%3开始了。输入操作数不用以+/=开头,其他的和输出操作数一样。额外多出来的就是这里会存在i 这个约束,表明这是一个立即数。cexpression部分则是一个C中的表达式。
clobber list:
一些汇编指令会产生副作用,可能会隐性的影响其他一些寄存器或者内存的指。这个时候需要将可能被影响的寄存器或者内存放到colbber list中。这个时候GCC会在必要的时候执行汇编指令前保存这些寄存器,等执行完后再进行恢复。