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指令而言,這是安全的。

TA貢獻1820條經驗 獲得超9個贊
想象一下這個“繪圖”
地址
xxx0123456789abcdef01234567 ...
[------] [------] [------] ...
寄存器
地址的值容易以8“ slide”的倍數進入(64位)寄存器
地址
56789abc ...
[------] [------] [------] ...
寄存器
當然要以8字節為步長來注冊“遍歷”
現在,如果您要將地址xxx5的值放入寄存器,則要困難得多:-)
編輯和-16
-16是二進制的11111111111111111111111111110000
當您用-16進行“和”運算時,您將得到一個最后4位設置為0 ...或16的倍數的值。
- 3 回答
- 0 關注
- 1056 瀏覽
添加回答
舉報