2012-01-10 95 views
3

我想在內聯彙編中使用線程局部變量,但是當我看到彙編代碼時,看起來編譯器不會生成正確的代碼。對於下面的內嵌代碼,其中saved_sp全球聲明爲__thread long saved_sp線程局部變量和內聯彙編

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

拆卸如下所示。

mov %rsp,0x612008 

這顯然是不正確的事情,因爲我知道,GCC使用FS段的線程局部變量。它應該產生像

mov %rsp, fs:somevalue 

它不是。爲什麼?在內聯彙編中使用線程局部變量是否有問題?

+0

我並不認爲海合會無論如何修改你的內聯彙編代碼。很可能你必須明確指定段覆蓋前綴。嘗試在'「movq%rsp,saved_sp \ n \ t」'之前插入'「.byte 0x64 \ n \ t」'。 – 2012-01-10 22:04:00

回答

4

一個簡單的事情,肯定會工作是採取一個指針的線程局部變量,並寫入它。
您的編譯器肯定會正確執行long *saved_fp_p = &saved_fp,並且內聯彙編將只處理saved_fp_p,這是一個局部變量。

您也可以使用gcc的輸入和輸出語法:

__asm__ __volatile__ (
    "mov %%rsp, 0(%0)" : : "r" (&saved_sp) 
); 

這讓負責解決saved_fp的地址的編譯器和彙編代碼得到它在寄存器中。

我們發現,這也適用,

__asm__ __volatile__ asm ("mov %rsp,%0" : "=m" (saved_sp)) 
+0

這是一個很好的解決方案,但我更願意直接寫入saved_sp,而不是使用寄存器指向它。 – MetallicPriest 2012-01-10 22:21:49

+1

也許'asm(「mov%rsp,%0」::「m」(saved_fp))'會起作用。重要的部分是讓編譯器而不是彙編程序處理saved_fp變量。編譯器肯定可以做到,彙編似乎做得很糟糕。 – ugoren 2012-01-10 22:32:09

+0

這確實有效!謝謝! – MetallicPriest 2012-01-10 22:46:40