我正在尝试使用GCC的内联汇编器来熟悉x86汇编。我试图添加两个数字(a
和b
)并将结果存储在c
中。我有四个稍微不同的尝试,其中三个工作;最后不会产生预期的结果。添加两个数字
前两个示例使用中间寄存器,并且这两个示例都正常工作。第三个和第四个示例尝试直接将这两个值相加,而不使用中间寄存器,但结果因优化级别和添加输入值的顺序而异。我错了什么?
环境是:
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
首先,变量的声明如下:
int a = 4;
int b = 7;
int c;
实施例1:
asm(" movl %1,%%eax;"
" addl %2,%%eax;"
" movl %%eax,%0;"
: "=r" (c)
: "r" (a), "r" (b)
: "%eax"
);
printf("a=%d, b=%d, c=%d\n", a, b, c);
// output: a=4, b=7, c=11
实施例2:
asm(" movl %2,%%eax;"
" addl %1,%%eax;"
" movl %%eax,%0;"
: "=r" (c)
: "r" (a), "r" (b)
: "%eax"
);
printf("a=%d, b=%d, c=%d\n", a, b, c);
// output: a=4, b=7, c=11
实施例3:
asm(" movl %2,%0;"
" addl %1,%0;"
: "=r" (c)
: "r" (a), "r" (b)
);
printf("a=%d, b=%d, c=%d\n", a, b, c);
// output with -O0: a=4, b=7, c=11
// output with -O3: a=4, b=7, c=14
实施例4:
// this one appears to calculate a+a instead of a+b
asm(" movl %1,%0;"
" addl %2,%0;"
: "=r" (c)
: "r" (a), "r" (b)
);
printf("a=%d, b=%d, c=%d\n", a, b, c);
// output with -O0: a=4, b=7, c=8
// output with -O3: a=4, b=7, c=11
解决。Matthew Slattery's answer是正确的。之前,试图重用eax
两个b
和c
:
movl -4(%rbp), %edx
movl -8(%rbp), %eax
movl %edx, %eax
addl %eax, %eax
有了马修的修复建议,它现在使用ecx
分别持有c
。
movl -4(%rbp), %edx
movl -8(%rbp), %eax
movl %edx, %ecx
addl %eax, %ecx
适用于我,无论是否启用优化。尝试使用-S编译,以获取汇编语言列表。然后您可以看到正在使用哪些寄存器。 – TonyK
只是注意到我根据优化级别得到不同的结果。代码示例使用新输出更新。 –
那么程序集清单告诉你什么? – TonyK