内联汇编:寄存器引用约定
在网上找到的 gcc 内联汇编示例中,我看到寄存器名称有时用一个 %
引用,有时用两个(即 %%
)引用.不清楚什么时候用单个 %
以及何时使用 %%
.例如请看下面的例子.
In gcc inline assembly examples found on the net, I see register names being referenced sometimes with a single %
and other times with two (i.e. %%
). It's not clear when to use
a single %
and when to use %%
.
e.g. please see below example.
/* 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,kernel 2.6.18, gcc 4.7.2). 但是下面的单行代码
This example which uses %%
prefix for EAX
register compiles fine on my x86 machine (Linux RedHat 5.6(Tikanga 2.6.18-238.5.1.el5 x86_64, kernel 2.6.18, gcc 4.7.2). But the following single line code
asm ("movl %%ecx, %%eax");
产生以下错误.
a.c: Assembler messages:
a.c:14: Error: bad register name `%%ecx'
有人能解释一下什么时候使用 %
以及什么时候使用 %%
吗?
Could someone please throw some light on when to use %
and when to use %%
?
谢谢.
在 asm
的主体内部(即实际代码所在的部分),您使用 %1
、%2
等引用 inline-asm 块的参数.为此,内联汇编将 %
视为特殊字符.
Inside the main body of the asm
(ie. the part where the actual code goes), you use %1
, %2
, etc. to refer to the arguments to the inline-asm block. The inline-asm treats %
as a special character for this purpose.
碰巧 x86 的 GNU 汇编器语法也使用 %
作为 x86 寄存器名称的前缀(%eax
、%ebx 等).但是,因为 inline-asm 为 %
分配了不同的含义,您必须将该块中的 %
加倍以对其进行转义.这就是为什么你会看到 movl %1, %%eax
:第一个 %1
扩展为一个参数,%%
在 前面>%%eax
被替换为单个 %
,从而在编译器的最终汇编输出中生成 %eax
.
It so happens that the GNU assembler syntax for x86 also uses %
as a prefix for the x86 register names (%eax
, %ebx
, etc.). But, because the inline-asm assigns different meaning to %
, you have to double up the %
in that block to escape it. That's why you see movl %1, %%eax
: The first %1
expands to an argument, the %%
in front of %%eax
gets replaced with a single %
, resulting in %eax
in the final assembly output by the compiler.
在代码块之后的其他字符串中,%
不再具有此特殊含义.这就是为什么在clobber列表中,例如,你只需要说%eax
.
In the other strings after the code block, %
doesn't have this special meaning any more. That's why in the clobber list, for example, you only need to say %eax
.
在您的第二个示例中,内联汇编器没有参数.没有 %1
... 替换说明符,因此您无需将 %
加倍.
In your second example, the inline assembler has no arguments. There are no %1
... substitution specifiers, and so you don't need to double up the %
.
像泥一样清澈?