2012-10-08 62 views
1

內訪問靜態的C變量當我嘗試從一個ASM揮發性裏面調用訪問靜態變量直接,我得到一個未定義的引用錯誤。我認爲有一種方法可以在不使用輸入和輸出寄存器的情況下做到這一點,但是我的搜索空着。從ASM揮發性通話

int main() { 
    static unsigned int a = 0; 
    __asm__ __volatile__("push a" : : :); 
    return 0; 
} 

error: undefined reference to a 

回答

0

嘗試:

__asm__ __volatile__ ("push " (a) : : :); 
+0

這似乎導致一個語法錯誤:預期「:」或「)」之前「(」 – allenylzhou

-1

花花公子,從雙引號去掉a

__asm__ __volatile__ ("push " (a) : : :); 
1

真的老問題,但由於沒有公認的答案...

第一所有,讓我說使用內聯彙編通常是一個bad idea。但如果你必須...

由於靜態是在一個函數內部聲明的,所以gcc需要一些方法來區分名爲a的main()和一個名爲foo()的靜態變量。它是如何實現的,但是在我的機器上構建,它使用了名稱a.2499。所以使用:

__asm__ __volatile__("push a.2499" : : :); 

工作。至少它做了一分鐘。當我對周圍的代碼做了一些小改動時,它將它改成了0.25。當然,執行這個語句後不久,應用程序因堆棧損壞而崩潰。

但這種方法還有其他問題。他們中的一些海合會docs來自這樣的說法:

GCC does not parse the assembler instructions themselves and does not know what they mean or even whether they are valid assembler input.

其結果是,這樣做的:

a++; 
__asm__ __volatile__("push a.2500" : : :); 
a++; 

不會做你期望的。即使-O1的最小優化將兩個a++語句合併爲一個addl $2, a.2500(%rip)。它這樣做是因爲編譯器沒有在asm中使用a的可見性,使用a作爲輸入提供的東西。

你可以用「有點」圍繞此聲明a揮發性。你可以(可能)通過使用全局變量解決命名問題。

但是,最好的解決方案(如果你真的必須使用內聯彙編)只是指定a作爲輸入。我看不到替代品的好處。

__asm__ __volatile__("push %0" 
    : /* no outputs */ 
    : "g" (a) /* input as a register, memory, or immediate operand */ 
    : /* no clobbers, because there's no way to tell gcc we're unbalancing the stack and clobbering the red-zone */ 
); 
+0

只是一個澄清:你的代碼註釋在討論過程中的紅色區域,使你實際上即使在假設一個紅色區域的環境。 –