2014-02-13 138 views
8

當運行使用gcc-4.8.1和-march=pentium4編譯代碼時,我在x86(32位)平臺上發生了一個神祕的總線錯誤。我將問題追溯到SSE指令:x86上的堆棧對齊方式

movdqa %xmm5,0x50(%esp) 

with esp = 0xbfffedac。 movdqa要求地址爲16字節對齊,這不是這種情況,因此總線錯誤。

如果使用-march=native(這是Core-i3處理器)進行編譯,則不會發生該問題。

據我所知,Linux/x86上唯一保證的堆棧對齊方式是4字節。因此,代碼生成器應該選擇使用movdqa,但沒有進行某種對齊檢查,即使存在可能未對齊的訪問的指令movdqu,這似乎很奇怪。

因此,這看起來像在gcc中存在一個錯誤。

我不是SSE和x86 ABI的專家,在發送錯誤報告之前,我會很感激你。

+0

您錯了,Linux/x86上的堆棧對齊有時可能是16個字節。請參閱[x86-64 ABI](http://www.x86-64.org/documentation/abi.pdf),[Linux基礎參考](http://refspecs.linuxbase.org/)和[x86調用約定](http://en.wikipedia.org/wiki/X86_calling_conventions) –

+0

這是x86,而不是x86-64 ......這是問題!該網站聲稱:「自GCC版本4.5以來,調用函數時,堆棧必須與16字節的邊界對齊(以前的版本只需要4字節的對齊方式)。」「引用需要」喜歡爲此獲得參考。 –

+0

請參閱[此評論](http://sourceforge.net/p/fbc/bugs/659/)。由於SSE,IIUC,32位x86/ia32上的堆棧對齊現在爲16個字節。如果GCC編譯器必須爲每個SSE代碼調整堆棧幀,則不值得痛苦和運行時成本。 –

回答

5

現在gcc中的默認值是-mpreferred-stack-boundary=4(16字節對齊),它設置了-mincoming-stack-boundary=4

如果使用SSE的gcc代碼是由其他編譯器生成的代碼調用的,例如OCaml(OCaml bug跟蹤器上的discussion)具有不同的堆棧對齊假設,則會出現問題。