【发布时间】:2014-03-11 23:29:55
【问题描述】:
我在 x86(32 位)平台上运行使用 gcc-4.8.1 和 -march=pentium4 编译的代码时发生了一个神秘的总线错误。我将问题追溯到 SSE 指令:
movdqa %xmm5,0x50(%esp)
与 esp = 0xbfffedac。 movdqa 要求地址是 16 字节对齐的,这里不是这样,因此总线错误。
如果使用-march=native(这是Core-i3 处理器)进行编译,则不会出现此问题。
据我所知,Linux/x86 上唯一保证的堆栈对齐是 4 字节。因此,代码生成器应该选择使用 movdqa 而不进行某种对齐检查似乎很奇怪,即使有一条指令 movdqu 用于可能未对齐的访问。
所以,看起来 gcc 中存在错误。
我不是 SSE 和 x86 ABI 方面的专家,在发送错误报告之前,我希望得到反馈。
【问题讨论】:
-
你错了,Linux/x86 上的堆栈对齐有时可以是 16 字节。请参阅x86-64 ABI、Linux foundation references 和 x86 calling conventions
-
这是 x86,而不是 x86-64……这就是问题所在!该网站声称:“从 GCC 4.5 版开始,调用函数时堆栈必须与 16 字节边界对齐(以前的版本只需要 4 字节对齐。)[需要引用]”“需要引用”,我会想获得参考。
-
见this comment。由于 SSE、IIUC,32 位 x86/ia32 上的堆栈对齐现在是 16 字节。如果 GCC 编译器必须为每个 SSE 代码对齐堆栈帧,那么痛苦和运行时成本将不值得。
-
啊啊,我确实在gcc文档中找到了有关x86代码生成的相关段落。似乎 OCaml 未对齐堆栈(并且因为它仅在调用包含一些 SSE 指令的代码时才显示......)。
-
@monniaux,为什么
march=pentium4会导致问题而不是march=native?