亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

堆棧分配,填充和對齊

堆棧分配,填充和對齊

C
開滿天機 2019-09-02 16:50:06
我一直在努力深入了解編譯器如何生成機器代碼,更具體地說是GCC如何處理堆棧。在這樣做的過程中,我一直在編寫簡單的C程序,將它們編譯成匯編并盡力理解結果。這是一個簡單的程序及其生成的輸出:asmtest.c:void main() {    char buffer[5];}asmtest.s:pushl   %ebpmovl    %esp, %ebpsubl    $24, %espleaveret讓我感到困惑的是為什么要為堆棧分配24個字節。我知道由于處理器如何尋址內存,堆棧必須以4為增量進行分配,但如果是這種情況,我們應該只將堆棧指針移動8個字節而不是24個。作為參考,緩沖區為17 bytes產生一個移動40個字節的堆棧指針,并且根本沒有緩沖區移動堆棧指針8. 1到16個字節之間的緩沖區移動ESP24個字節?,F在假設8個字節是必要的常量(它需要什么?),這意味著我們分配16個字節的塊。為什么編譯器會以這種方式對齊?我正在使用x86_64處理器,但即使是64位字也只需要8字節對齊。為什么會出現差異?作為參考,我正在使用gcc 4.0.1運行10.5的Mac上進行編譯,并且未啟用任何優化。
查看完整描述

4 回答

?
楊魅力

TA貢獻1811條經驗 獲得超6個贊

它是一個gcc功能,由-mpreferred-stack-boundary=n編譯器試圖保持堆棧上的項目對齊的位置控制2^n。如果更改n為2,則只會在堆棧上分配8個字節。默認值n是4ie它將嘗試對齊到16字節邊界。


為什么有“默認”的8個字節,然后24 = 8 + 16個字節是因為棧已經包含8個字節的leave和ret,所以編譯后的代碼必須是8個字節首先調整堆得到它對齊到2 ^ 4 = 16。


查看完整回答
反對 回復 2019-09-02
?
慕標琳琳

TA貢獻1830條經驗 獲得超9個贊

SSEx系列指令要求打包128位向量以對齊16個字節 - 否則會出現嘗試加載/存儲它們的段錯誤。即如果你想安全地傳遞16字節向量以便在堆棧上使用SSE,則堆棧需要始終保持與16對齊。默認情況下,GCC會對此進行說明。


查看完整回答
反對 回復 2019-09-02
?
元芳怎么了

TA貢獻1798條經驗 獲得超7個贊

它在頁面底部有一些關于堆棧可能更大的原因。將概念擴展到64位機器,它可能會解釋您所看到的內容。


查看完整回答
反對 回復 2019-09-02
?
幕布斯7119047

TA貢獻1794條經驗 獲得超8個贊

Mac OS X / Darwin x86 ABI需要16字節的堆棧對齊。在Linux,Win32,FreeBSD等其他x86平臺上情況并非如此......


查看完整回答
反對 回復 2019-09-02
  • 4 回答
  • 0 關注
  • 651 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號