一千萬個為什麽

搜索

GCC不在函數調用中保存/恢復保留寄存器

我在GCC有一個場景給我帶來了問題。我得到的行為不是我期望的行為。總結一下這種情況,我提出了一些x86-64的新指令,這些指令是在硬件模擬器中實現的。為了測試這些指令,我使用現有的C源代碼並使用十六進制對新指令進行手動編碼。因為這些指令與現有的x86-64寄存器交互,所以我使用input/output/clobber列表來聲明GCC的依賴關系。

發生的事情是,如果我調用一個函數,例如printf,不保存和恢復從屬寄存器。

例如

register unsigned long r9  asm ("r9")  = 101;
printf("foo %s\n", "bar");
asm volatile (".byte 0x00, 0x00, 0x00, 0x00" : /* no output */ : "q" (r9) );

101被分配給r9,並且內聯匯編(在此示例中為假)依賴於r9。這在沒有printf的情況下正確運行,但是當它存在時,GCC不會保存和恢復r9,並且在調用自定義指令時會有另一個值。

我想也許GCC可能秘密地將賦值更改為變量 r9,但是當我這樣做時

asm volatile (".byte %0" : /* no output */ : "q" (r9) );

看看匯編輸出,確實使用的是%r9。

我正在使用gcc 4.4.5。您認為可能會發生什麽?我認為GCC將始終在函數調用中保存和恢復寄存器。有什麽方法可以強制執行嗎?

謝謝!

編輯:順便說一下,我正在編譯這樣的程序

gcc -static -m64 -mmmx -msse -msse2 -O0 test.c -o test

最佳答案

ABI ,第3.2.1節說:

註冊%rbp,%rbx和%r12到%r15“屬於”調用函數和   叫做函數是   需要保持他們的價值觀。換句話說,被調用的函數必須保留   這些寄存器的值為其調用者。剩余的寄存器“屬於”被叫   功能。如果調用函數想要在a中保留這樣的寄存器值   函數調用時,必須將值保存在本地堆棧框架中。

所以你不應該期望函數調用保留除%rbp,%rbx和%r12到%r15之外的寄存器。

轉載註明原文: GCC不在函數調用中保存/恢復保留寄存器