int main(void)
{
int x = 10, y;
asm ("movl %1, %%eax;" "movl %%eax, %0;" :"=r"(y) :"r"(x) :"%eax");
/* y is output operand */
/* x is input operand */
/* eax is clobbered register */
return 0;
}
生成的汇编代码如下:
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl $10, -4(%ebp)
movl -4(%ebp), %edx /* x=10 is stored in %edx */,#APP
movl %edx, %eax /* x is moved to eax */
movl %eax, %edx /* y is allocated in edx and updated */,#NO_APP
movl %edx, -8(%ebp) /* value of y in the stack is updated with the value in edx */
“r”指明GCC可以采用任意的寄存器。在上例中,edx被先后用于存放x和y。
由于eax在clobbered list中,GCC不会使用它去存放数据。
在上例中,edx被先后用于输入和输出,这里有一个前提就是输入数据总是在输出之前就已经失效了。但是实际情况中有很多指令并不总是这样做的,所以我们可以加上“&”修饰符让输入输出使用不同的寄存器。
int main(void){ int x = 10, y; asm ("movl %1, %%eax;" "movl %%eax, %0;" :"=r"(y) /* y is output operand, note the "&" modifier */ :"r"(x) /* x is input operand */ :"%eax");/* eax is clobbered register */ return 0;}
生成下面代码:
main: pushl %ebp movl %esp, %ebp subl $8, %esp movl $10, -4(%ebp) movl -4(%ebp), %ecx /* x=10 is stored in %ecx */,#APP movl %ecx, %eax movl %eax, %edx /* output is in %edx */,#NO_APP movl %edx, -8(%ebp)