我正在嘗試使用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