2012-04-20 41 views

回答

9

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

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

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

如果将默认值更改为例如-mpreferred-stack-boundary=2,那么GCC将在4字节边界上对齐堆栈指针。这将减少您的例程的堆栈要求,但是如果您的代码(或您调用的代码)确实使用使用sse2,则会崩溃,因此通常不安全。

+2

+1值得一提的是,实际边界大小为2^PSB。如果将此参数设置为2,则会得到2^2 = 4的边界大小。如果将其设置为4,则会得到2^4 = 16的边界大小。 – 2014-08-24 02:45:11

0

它与您的程序在内存中放置时使用的字节边界有关。

堆栈边界= 2所做的是确保将堆栈设置为dword大小的增量,这可以防止机器优化堆栈。

如果你看看:

`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-优选堆叠边界= 2” 选项在我的64位Linux机器编译失败,错误

“-mpreffered堆叠边界= 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。