在寄存器约束下,扩展 GCC asm 中的多个输入和输出操作数的正确使用是什么?考虑一下我的问题的最小版本。下面简要介绍 GCC、AT&T 语法的扩展 asm 代码:
int input0 = 10;
int input1 = 15;
int output0 = 0;
int output1 = 1;
asm volatile("mov %[input0], %[output0]\t\n"
"mov %[input1], %[output1]\t\n"
: [output0] "=r" (output0), [output1] "=r" (output1)
: [input0] "r" (input0), [input1] "r" (input1)
:);
printf("output0: %d\n", output0);
printf("output1: %d\n", output1);
语法显示正确基于https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html然而,我一定是忽略了一些事情,或者犯了一些我因某种原因而看不到的小错误。
GCC 5.3.0 p1.0(无编译器参数)的输出为:
输出0:10
输出1:10
预期输出是:
输出0:10
输出1:15
在 GDB 中查看显示:
0x0000000000400581 :mov eax,DWORD PTR [rbp-0x10]
0x0000000000400584 :mov edx,DWORD PTR [rbp-0xc]
0x0000000000400587 : mov edx,eax
0x0000000000400589 : mov eax,edx
0x000000000040058b :mov DWORD PTR [rbp-0x8],edx
0x000000000040058e : mov DWORD PTR [rbp-0x4],eax
据我所见,它使用 input0 加载 eax,使用 input1 加载 edx。然后它用 eax 覆盖 edx,用 edx 覆盖 eax,使它们相等。然后将它们写回output0 和output1。
如果我对输出使用内存约束 (=m) 而不是寄存器约束 (=r),它会给出预期的输出,并且程序集看起来更合理。