【问题标题】:Stack alignment on x86x86 上的堆栈对齐
【发布时间】: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 ABILinux foundation referencesx86 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

标签: linux gcc x86 sse


【解决方案1】:

现在 gcc 中的默认值是-mpreferred-stack-boundary=4(16 字节对齐),它设置了-mincoming-stack-boundary=4

如果使用 SSE 的 gcc 代码是从具有不同堆栈对齐假设的其他编译器生成的代码中调用的,则可能会出现问题,例如 OCaml(请参阅 OCaml 错误跟踪器上的 discussion)。

【讨论】:

    猜你喜欢
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 2015-11-20
    • 2011-06-25
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多