问题
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 */
);
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");
produces the error below.
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 %% ?
Thank you.
回答1:
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.
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.
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.
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 %.
Clear as mud?
来源:https://stackoverflow.com/questions/20510678/inline-assembly-register-referencing-conventions