我想知道在GNU编译器编译期间-mpreferred-stack-boundary
选项的用途是什么。我已经检查了文档,但解释丢失了。有人可以解释一下。
答案 0 :(得分:12)
我想知道在GNU调试器的编译过程中使用-mpreferred-stack-boundary选项有什么用。
该选项与调试器的绝对没有。
它会影响二进制文件中生成的代码。默认情况下,GCC将安排一些事情,以便每个函数在进入后立即将其堆栈指针对齐在16字节边界上(如果您有局部变量,并且启用sse2
指令,这可能很重要。)
如果您将默认设置更改为例如-mpreferred-stack-boundary=2
,然后GCC将堆栈指针对齐在4字节边界上。这将减少您的例程的堆栈需求,但如果您的代码(或您调用的代码) 使用sse2
,则会崩溃,因此通常不安全。
答案 1 :(得分:0)
它与程序在内存中布局时使用的字节边界有关。
堆栈边界= 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。
当我尝试使用" m-preferred-stack-boundary = 2"我的64位Linux机器编译选项失败,错误
" -mpreffered-stack-boundary = 2不在4到12"之间。
这是因为64位机器中地址字段的宽度从4个字节增加到8个字节。因此它不能在堆栈边界= 2处写入单个块,因为2 ^ 2 = 4个字节。但是,有趣的是,堆栈边界为3仍会在32位和64位机器上返回错误,这将是一个8字节的边界。
我无法包含该链接,因为我没有10个声誉......但搜索很容易 据我所知,这是一个安全功能,因为8个字节容易使堆栈错位...毫无疑问,其他人知道的更好,或者有更多细节。
How the stack got misaligned 表示:
为确保在堆栈上正确对齐此值,堆栈边界必须与存储在堆栈中的任何值所需的对齐。此外,必须生成每个函数,使其保持堆栈对齐。因此,从使用较低优选堆栈边界编译的函数调用使用较高优选堆栈边界编译的函数很可能使堆栈不对齐。建议使用回调的库始终使用默认设置。
这种额外的对齐会消耗额外的堆栈空间,并且通常会增加代码大小。对堆栈空间使用敏感的代码(例如嵌入式系统和操作系统内核)可能希望将首选对齐减少到-mpreferred-stack-boundary = 2。
答案 2 :(得分:0)
是的,使用-mpreferred-stack-boundary with 2来轻松地反汇编正在进行的操作是很有用的,否则它将被优化并且很难跟踪堆栈中正在发生的事情。对于64位右边,你至少需要4个