linux 程序內存模型

說明:

已初始化的全局變量存儲在.dada數據段;為初始化的全局變量位於.bss為初始化數據段。靜態全局變量也在.data數據段局部變量在棧上,靜態局部變量,並不是在調用函數時分配,並不是在函數返回時釋放,其跟全局變量一樣靜態分配,在.data數據段,但作用域只在函數中 const 修飾的變量在.rodata只讀段,只讀段與.text在同一個segment。

  1. 代碼段:代碼段(code segment/text segment)通常是指用來存放程序執行代碼的一塊內存區域。
  2. 這部分區域的大小在程序運行前就已經確定,並且內存區域通常屬於只讀, 某些架構也允許代碼段
  3. 為可寫,即允許修改程序。在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。
  4. 程序在被載入內存後,會被分為很多小的區(section),有一個rodata區(也就是常量區),
  5. 常量區的數據內存中的位置為代碼段,存放的數據為字符串、const修飾的常量(全局的或是靜態的,
  6. odata區,而這個字符串的地址也就是指針s存放在數據段中(程序載入內存中為.data區)。
  7. 再如,static char *const s=”hello,world”;那麼這時候不僅”hello,world”字符串存放在rodata區,
  8. 指針s也同樣。
  9. 數據段:數據段(data segment)通常是指用來存放程序中已初始化的全局變量或者靜態變量的
  10. 一塊內存區域。數據段屬於靜態內存分配。原則上數據段所對應的內存區數據是可以改變的。
  11. 這裡沒有提到局部變量,這是因為局部變量一般都存放在棧中。局部變量不管是否有const修飾
  12. 都存放在棧中,例如char *const lcp=”999”;字符竄”999”存放在代碼段的rodata區,這個沒有說的,
  13. 而它對應的地址lcp指針存放在棧中;
  14. BSS段:BSS段(bss segment)通常是指用來存放程序中未初始化的全局變量的一塊內存區域。
  15. BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態內存分配。例如全局變量int i;
  16. 靜態變量static int si;都存放在這裡面。
  17. 堆(heap):堆是用於存放進程運行中被動態分配的內存段,它的大小並不固定,可動態擴張或縮減。
  18. 當進程調用malloc等函數分配內存時,新分配的內存就被動態添加到堆上(堆被擴張);
  19. 當利用free等函數釋放內存時,被釋放的內存從堆中被剔除(堆被縮減),要注意的是,
  20. 當分配的數據大小操作內核的限制時,內核採用匿名映射的方式實現而不是從堆中分配內存。
  21. 棧(stack):棧又稱堆棧, 是用戶存放程序臨時創建的局部變量,也就是說我們函數括弧“{}”
  22. 中定義的變量(但不包括static聲明的變量,static意味著在數據段或代碼段中存放變量)。
  23. 除此以外,在函數被調用時,其參數也會被壓入發起調用的進程棧中,並且待到調用結束後,
  24. 函數的返回值也會被存放回棧中。由於棧的先進先出特點,所以棧特別方便用來保存/恢復調用現場。
  25. 從這個意義上講,我們可以把堆棧看成一個寄存、交換臨時數據的內存區。

在進程被載入內存中時,基本上被分裂成許多小的節(section)。我們比較關注的是幾個主要的節:

  1. .text 節
  2. .text 節基本上相當於二進制可執行文件的.text部分,它包含了完成程序任務的機器指令。
  3. 該節標記為只讀,如果發生寫操作,會造成segmentation fault。在進程最初被加載到內存中開始,該節的大小就被固定。
  4. .data 節
  5. .data節用來存儲初始化過的變量,如:全局int a =0 ; 該節的大小在運行時固定的。
  6. .bss 節
  7. 棧下節(below stack section ,即.bss)用來存儲為初始化的變量,如:int a; 該節的大小在運行時固定的。
  8. 堆節
  9. 堆節(heap section)用來存儲動態分配的變量,位置從內存的低地址向高地址增長。內存的分配和釋放通過malloc() 和 free() 函數控制。
  10. 棧節
  11. 棧節(stack section)用來跟蹤函數調用(可能是遞歸的),在大多數系統上從內存的高地址向低地址增長。
  12. 同時,棧這種增長方式,導致了緩衝區溢出的可能性。
  13. .rodata節
  14. 常量區,全局或靜態const變量、指針存放區。
  15. 環境/參數節
  16. 環境/參數節(environment/arguments section)用來存儲系統環境變量的一份複製文件,
  17. 進程在運行時可能需要。例如,運行中的進程,可以通過環境變量來訪問路徑、shell 名稱、主機名等信息。
  18. 該節是可寫的,因此在格式串(format string)和緩衝區溢出(buffer overflow)攻擊中都可以使用該節。
  19. 另外,命令行參數也保持在該區域中。


分享到:


相關文章: