簡體   English   中英

如何在gcc內聯匯編中使用全局變量

[英]How to use a global variable in gcc inline assembly

我試圖使用這樣的內聯匯編,作為全局變量,但編譯器通過對saved_sp的未定義引用給出錯誤。

__asm__ __volatile__ (
        "movq saved_sp, %rsp\n\t" );

saved_sp被聲明為static long saved_sp (對於一個文件)。 我在這做什么錯?

如果它失敗並且“未定義引用`saved_sp'”(這實際上是一個鏈接器錯誤,而不是編譯器錯誤)當saved_spstatic ,但是當它不是時工作,那么編譯器似乎已經確定saved_sp不是在源文件中使用,因此決定從傳遞給匯編程序的已編譯代碼中完全省略它。

編譯器不理解asm塊內的asm代碼; 它只是將其粘貼到它生成的匯編代碼中。 因此,它不知道asm塊引用saved_sp ,如果C代碼中沒有其他內容可以從中讀取,則可以自由決定它是否完全未使用 - 特別是如果您啟用了任何優化選項。

你可以告訴gccsaved_sp被它看不到的東西使用,因此通過添加used屬性阻止它選擇扔掉它(參見變量屬性文檔 ,大約在頁面的中間),例如:

static long __attribute__((used)) saved_sp;

這是一個完整的例子:

$ cat test.c
#ifdef FIXED
static long __attribute__((used)) saved_sp;
#else
static long saved_sp;
#endif

int main(void)
{
  __asm__ __volatile__ (
        "movq saved_sp, %rsp\n\t" );
}

$ gcc -m64 -o test test.c
$ gcc -m64 -O1 -o test test.c
/tmp/ccATLdiQ.o: In function `main':
test.c:(.text+0x4): undefined reference to `saved_sp'
collect2: ld returned 1 exit status
$ gcc -m64 -DFIXED -O1 -o test test.c
$ 

(這是來自32位Debian擠壓系統,帶有gcc 4.4.5,這是我最接近的東西; -m64在您的系統上可能是不必要的。)

您最好使用輸入和輸出參數:

__asm__ __volatile__ ( 
    "movq %0, %%rsp\n\t"
    : : "r"(saved_sp) : "memory"
);

在組裝階段通常可能存在一些根本不是符號的變量(例如堆棧變量或寄存器。另外,你想要破壞整個內存,以確保在saved_sp之后沒有堆棧變量保存在寄存器中存儲在RSP中。

正如我在評論中指出的那樣,以下在64位Ubuntu上使用gcc 4.4.4編譯(並生成正確的機器代碼):

long saved_sp;

int main() {
  __asm__ __volatile__ (
        "movq saved_sp, %rsp\n\t" );
}

也許這個問題可能完全是另一回事(缺少#include ,以至於saved_sp實際上沒有被定義? 編輯 :現在你說它是static ,我想這不太可能。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM