2014-02-13 139 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)具有不同的堆栈对齐假设,则会出现问题。