2012-04-20 68 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。