[英]Inline assembly : register referencing conventions
在网上找到的gcc内联汇编示例中,我看到有时使用单个%
引用寄存器名称,有时使用两个引用(即%%
)。 目前尚不清楚何时使用单个%
以及何时使用%%
。 例如,请看下面的例子。
/* Do b = a */
int a=10, b;
asm ("movl %1, %%eax;\n"
"movl %%eax, %0;"
: "=r" (b) /* output */
: "r" (a) /* input */
: "%eax" /* clobbered register */
);
这个在EAX
寄存器上使用%%
前缀的例子在我的x86机器上编译得很好(Linux RedHat 5.6(Tikanga 2.6.18-238.5.1.el5 x86_64,内核2.6.18,gcc 4.7.2)。但是下面的单行代码
asm ("movl %%ecx, %%eax");
产生以下错误。
a.c: Assembler messages:
a.c:14: Error: bad register name `%%ecx'
有人可以请问什么时候使用%
以及何时使用%%
?
谢谢。
在asm
的主体内部(即实际代码所在的部分),使用%1
, %2
等来引用inline-asm块的参数。 为此目的,inline-asm将%
视为特殊字符。
碰巧x86的GNU汇编语法也使用%
作为x86寄存器名称的前缀( %eax
, %ebx
等)。 但是,因为inline-asm为%
赋予不同的含义,所以你必须将该块中的%
加倍以逃避它。 这就是为什么你看到movl %1, %%eax
:第一%1
扩展到一个参数, %%
前面%%eax
获取与单取代%
,致使%eax
在编译器的最终输出组件。
在代码块之后的其他字符串中, %
不再具有此特殊含义。 这就是为什么在clobber列表中,例如,你只需要说%eax
。
在第二个示例中,内联汇编程序没有参数。 没有%1
...替换说明符,因此您不需要将%
加倍。
像泥一样清楚?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.