GCC擴展內聯彙編關於寄存器的一點問題

源碼

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int result = 0;
    int input = 1;
    __asm__ __volatile__ ("addl %2,%0":"=r"(result): "r"(result),"r"(input));
    printf("The result = %d\n",result);
    return 0;
}

反彙編:

0x00401343	movl   $0x0,0x1c(%esp)
0x0040134B	movl   $0x1,0x18(%esp)
0x00401353	mov    0x1c(%esp),%eax
0x00401357	mov    0x18(%esp),%edx
0x0040135B	add    %edx,%ebx   #這裏ebx的內容是不確定的
0x0040135D	mov    %ebx,0x1c(%esp)

按照預計,應該會把result和input都放到寄存器中,如result放到edx,input放到eax中。然後執行addl %eax,%edx.但是反彙編的結果是addl %edx,%ebx。也就是addl的目的操作數一直是ebx。而ebx中是一個不確定的值,所以結果一直不對。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在上面的代碼中不能確保輸出參數result和第一個輸入參數result一定被放在同一個寄存器中了,所以下面用了一個比較穩妥的方法。使用佔位符,保證他倆存在一個register中。

0x00401343	movl   $0x0,0x1c(%esp)
0x0040134B	movl   $0x1,0x18(%esp)
0x00401353	mov    0x1c(%esp),%edx
0x00401357	mov    0x18(%esp),%eax
0x0040135B	mov    %edx,%ebx
0x0040135D	add    %eax,%ebx
0x0040135F	mov    %ebx,0x1c(%esp)

因爲使用的"r",編譯器會自己安排通用寄存器來放置變量。可見開始的時候,result被放在edx中。後來應該使用佔位符,使得第一個輸入參數和輸出參數使用同一個寄存器。從倒數第2,3條指令中可見,它將edx中的內容mov到ebx中。然後再執行addl指令。

所以這裏考慮,是不是編譯器進行優化或者是規定了擴展內聯彙編中輸出變量默認存在ebx中?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章