關於虛擬地址空間

http://blog.chinaunix.net/uid-26606708-id-3073559.html

很不錯的代碼解析和棧分析:http://blog.csdn.net/iterzebra/article/details/6206420


棧的結構:http://www.cnblogs.com/bugman/archive/2011/09/29/2195879.html



關於棧的結構

棧結構(參數入棧順序跟調用方式有關,這裏以C語言默認的CDECL爲例(參數由右向左進入堆棧)):
| ....................|     (棧底方向,高位地址) 
| 參數3 |
| 參數2 |
| 參數1 |
| 返回地址 |
-| 上一層[EBP] |
| 局部變量2 |
| 局部變量1 |     
|.....................|    (棧頂方向,低位地址)

棧一直隨着函數調用的深入,一直想棧頂方向壓下去。每次調用函數時候,先壓函數參數(從右往左順序壓),再壓入函數調用下條指令的地址(由call完成)。接着進入調用函數體中先執行pushq %rbp; movq %rsp, %rbp(一般已經由編譯器加入到函數頭中了),接着就是吧函數體中的局部變量壓入棧中。再遇到函數的調用的嵌套則依此類推。(added by smsong)

pushq %rbp; movq %rsp, %rbp這兩條指令實在大有深意:首先將rbp入棧,然後將棧頂指針rsp賦值給rbp。
movq %rsp, %rbp這條指令表面上看是用rsp把原來rbp的值覆蓋了,其實不然——因爲給rbp賦值之前,原rbp值已被壓棧(位於棧頂),而新的rbp又恰恰指向棧頂
  此時rbp寄存器就已處於一個很重要的地位,該寄存器中存儲着棧中的一個地址(原rbp入棧後的棧頂),從該地址爲基準,向上(棧底方向)能獲取返回地址、參數值,向下(棧頂方向)能獲取函數局部變量值,而該地址處又存儲着上一層函數調用時的rbp值!




進程的虛擬地址空間

| ....................|

| ....................|

|內核虛擬存儲器|                (高位地址)

|用戶棧(運行時創建)|

|共享庫的存儲器的映射區域|

|運行時堆|

|讀/寫數據|

|只讀的代碼和數據|

|未用|                                                (低位地址)

| ....................|

| ....................|


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章