问题 gcc -mpreferred-stack-boundary选项


我想知道它的用途是什么 -mpreferred-stack-boundary GNU编译器编译期间的选项。我查了一下文档,但解释丢失了。有人可以解释一下吗。


9286
2018-04-20 18:01


起源



答案:


我想知道在GNU调试器的编译过程中使用-mpreferred-stack-boundary选项有什么用。

选项有 绝对没有 与调试器有关。

它会影响二进制文件中生成的代码。默认情况下,GCC将安排一些事情,以便每个函数在进入后立即将其堆栈指针对齐在16字节边界上(如果您有局部变量,这可能很重要,并且启用 sse2 说明)。

如果您将默认值更改为例如 -mpreferred-stack-boundary=2,然后GCC将堆栈指针对准4字节边界。这将减少您的例程的堆栈需求,但如果您的代码(或您调用的代码)将崩溃  使用 sse2,所以一般不安全。


12
2018-04-21 04:37



+1值得一提的是实际边界大小为2 ^ PSB。如果将此参数设置为2,则边界大小为2 ^ 2 = 4。如果将其设置为4,则边界大小为2 ^ 4 = 16。 - Mark E. Haase


答案:


我想知道在GNU调试器的编译过程中使用-mpreferred-stack-boundary选项有什么用。

选项有 绝对没有 与调试器有关。

它会影响二进制文件中生成的代码。默认情况下,GCC将安排一些事情,以便每个函数在进入后立即将其堆栈指针对齐在16字节边界上(如果您有局部变量,这可能很重要,并且启用 sse2 说明)。

如果您将默认值更改为例如 -mpreferred-stack-boundary=2,然后GCC将堆栈指针对准4字节边界。这将减少您的例程的堆栈需求,但如果您的代码(或您调用的代码)将崩溃  使用 sse2,所以一般不安全。


12
2018-04-21 04:37



+1值得一提的是实际边界大小为2 ^ PSB。如果将此参数设置为2,则边界大小为2 ^ 2 = 4。如果将其设置为4,则边界大小为2 ^ 4 = 16。 - Mark E. Haase


它与程序在内存中布局时使用的字节边界有关。

堆栈边界= 2的作用是确保堆栈设置为双字大小增量,这可以防止机器优化堆栈。

如果你结账:

`info gcc and search by entering "/mpreferred-stack-boundary"` it says:
>-mpreferred-stack-boundary=num
> 

尝试保持堆栈边界对齐到num字节边界的2。如果未指定-mpreferred-stack-boundary,则默认值为4(16字节或128位)。

对于Intel 386和AMD x86-64计算机,默认堆栈边界为4是相同的。

当我尝试在我的64位Linux机器上使用“m-preferred-stack-boundary = 2”选项时,编译失败并出现错误

“-mpreffered-stack-boundary = 2不在4到12之间”。

这是因为64位机器中地址字段的宽度从4个字节增加到8个字节。因此它不能在堆栈边界= 2处写入单个块,因为2 ^ 2 = 4个字节。但是,有趣的是,堆栈边界为3仍会在32位和64位机器上返回错误,这将是一个8字节的边界。

我不能包含这个链接,因为我没有10个声望......但是搜索很容易变成东西 据我所知,它是一个安全功能,因为8个字节容易使堆栈不对齐......毫无疑问,其他人知道更好,或者有更多细节。

堆栈是如何错位的 说:

为了确保在堆栈上正确对齐这些值,堆栈边界必须与存储在堆栈中的任何值所需的对齐。此外,必须生成每个函数,使其保持堆栈对齐。因此,从使用较低优选堆栈边界编译的函数调用使用较高优选堆栈边界编译的函数很可能使堆栈不对齐。建议使用回调的库始终使用默认设置。

这种额外的对齐会消耗额外的堆栈空间,并且通常会增加代码大小。对堆栈空间使用敏感的代码(例如嵌入式系统和操作系统内核)可能希望将首选对齐减少为-mpreferred-stack-boundary = 2。


0
2018-03-27 19:22



回覆。堆栈边界为3,请参阅bug: gcc.gnu.org/bugzilla/show_bug.cgi?id=53383 - wulfgarpro


是的,使用-mpreferred-stack-boundary with 2来轻松地反汇编正在进行的操作是很有用的,否则它将被优化并且难以跟踪堆栈中发生的事情。对于64位,你至少需要4位


0
2018-04-26 10:50