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

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

對齊堆棧是什么意思?

對齊堆棧是什么意思?

C
江戶川亂折騰 2019-11-11 15:45:11
我一直是高級編碼人員,而體系結構對我來說還很新,所以我決定在此處閱讀有關Assembly的教程:http://en.wikibooks.org/wiki/X86_Assembly/Print_Version在教程的最下方,提供了有關如何轉換Hello World的說明!程序#include <stdio.h>int main(void) {    printf("Hello, world!\n");    return 0;}給出了等效的匯編代碼,并生成了以下代碼:        .textLC0:        .ascii "Hello, world!\12\0".globl _main_main:        pushl   %ebp        movl    %esp, %ebp        subl    $8, %esp        andl    $-16, %esp        movl    $0, %eax        movl    %eax, -4(%ebp)        movl    -4(%ebp), %eax        call    __alloca        call    ___main        movl    $LC0, (%esp)        call    _printf        movl    $0, %eax        leave        ret對于其中一條線,andl    $-16, %esp原因是:此代碼用0xFFFFFFF0“和” ESP,使堆棧與下一個最低的16字節邊界對齊。對Mingw的源代碼進行檢查后發現,這可能適用于出現在“ _main”例程中的SIMD指令,該指令僅在對齊的地址上運行。由于我們的例程不包含SIMD指令,因此此行是不必要的。我不明白這一點。有人可以給我解釋一下將堆棧與下一個16字節邊界對齊是什么意思,為什么要這樣做?以及如何andl實現這一目標?
查看完整描述

3 回答

?
吃雞游戲

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

假設堆棧在進入時看起來像這樣_main(堆棧指針的地址只是一個示例):


|    existing     |

|  stack content  |

+-----------------+  <--- 0xbfff1230

按下%ebp,然后減去8,%esp為局部變量保留一些空間:


|    existing     |

|  stack content  |

+-----------------+  <--- 0xbfff1230

|      %ebp       |

+-----------------+  <--- 0xbfff122c

:    reserved     :

:     space       :

+-----------------+  <--- 0xbfff1224

現在,andl指令將的低4位清零%esp,這可能會減少它;在此特定示例中,它具有保留額外的4個字節的效果:


|    existing     |

|  stack content  |

+-----------------+  <--- 0xbfff1230

|      %ebp       |

+-----------------+  <--- 0xbfff122c

:    reserved     :

:     space       :

+ - - - - - - - - +  <--- 0xbfff1224

:   extra space   :

+-----------------+  <--- 0xbfff1220

這樣做的重點是存在一些“ SIMD”(單指令,多數據)指令(在x86-land中也稱為“流SIMD擴展”的“ SSE”),它們可以對內存中的多個字執行并行操作,但是要求這些多個字成為從16字節倍數的地址開始的塊。


通常,編譯器無法假定的特定偏移量%esp會導致產生合適的地址(因為%esp該函數的進入狀態取決于調用代碼)。但是,通過以這種方式故意對齊堆棧指針,編譯器知道向堆棧指針添加16字節的任何倍數將導致16字節對齊的地址,對于這些SIMD指令而言,這是安全的。


查看完整回答
反對 回復 2019-11-11
?
慕妹3146593

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

想象一下這個“繪圖”


地址

 xxx0123456789abcdef01234567 ...

    [------] [------] [------] ...

寄存器

地址的值容易以8“ slide”的倍數進入(64位)寄存器


地址

         56789abc ...

    [------] [------] [------] ...

寄存器

當然要以8字節為步長來注冊“遍歷”


現在,如果您要將地址xxx5的值放入寄存器,則要困難得多:-)


編輯和-16


-16是二進制的11111111111111111111111111110000


當您用-16進行“和”運算時,您將得到一個最后4位設置為0 ...或16的倍數的值。


查看完整回答
反對 回復 2019-11-11
  • 3 回答
  • 0 關注
  • 1056 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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