下圖是x86_64下linux程序的預設記憶體布局形式:
下面逐一分析以上各個位址段的含義。
text **段
**段,從虛擬記憶體位址00400000開始,使用pmap $$可以檢視到,這個位址是固定的:
linux # pmap $$
27729: bash
00400000 552k 480k 260k 0k 0k r-xp /bin/bash
00689000 4k 4k 4k 4k 0k r--p /bin/bash
0068a000 20k 20k 20k 20k 0k rw-p /bin/bash
0068f000 1420k 1356k 1356k 1356k 0k rw-p [heap]
7f4f47b72000 64k 4k 4k 0k 0k r-xp /usr/lib64/gconv/libgb.so
……7f4f48c33000 4k 4k 4k 4k 0k rw-p [anon]
7fff0f0f1000 84k 20k 20k 20k 0k rw-p [stack]
7fff0f1ff000 4k 4k 0k 0k 0k r-xp [vdso]
ffffffffff600000 4k 0k 0k 0k 0k r-xp [vsyscall]
total: 18944k 3256k 2225k 1580k 0k
1652k writable-private, 17052k readonly-private, 240k shared, and 3256k referenced
00400000位址段用於存放程式的可執行檔案,fork乙個子程序,之後呼叫execve載入可執行檔案,execve即將檔案載入到該段位址中:
linux # strace ls
execve("/bin/ls", ["ls"], [/* 65 vars */]) = 0
brk(0) =0x618000
mmap(null, 4096, prot_read | prot_write, map_private | map_anonymous, -1, 0) = 0x7f0422e2a000……
data 資料段
資料段用於存放已初始化全域性變數。
bss段
該段用於存放全域性的、但未初始化的變數。bss段與data段的區別是,編譯時需為data段分配空間,而bss段不用。資料存放於bss段,減小了可執行程式的檔案大小。
heap
堆,c庫中的malloc呼叫就是從該段獲取記憶體空間。
memory map
mmap系統呼叫可將檔案對映入程序memory map位址空間。使用pmap $$檢視,[heap]下面部分就是mmap區域,對於以上"pmap $$"輸出:
7f4f47b72000 64k 4k 4k 0k 0k r-xp /usr/lib64/gconv/libgb.so
bash程序將/usr/lib64/gconv/libgb.so檔案對映到以7f4f47b72000開頭的位址段。
使用ldd命令,我們可以看到程序依賴的庫檔案,這些庫檔案編譯過程中都要關聯到程序的虛擬位址空間:
linux # ldd /bin/bash
linux-vdso.so.1 => (0x00007fffc73ff000)
libreadline.so.5 => /lib64/libreadline.so.5 (0x00007f7effe50000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f7effc4c000)
libc.so.6 => /lib64/libc.so.6 (0x00007f7eff8ee000)
libncurses.so.5 => /lib64/libncurses.so.5 (0x00007f7eff6a6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7f00092000)
stack
存放區域性變數,從高位址向低位址生長。
核心**中,mm_struct結構用於描述乙個程序的位址空間。
vm_area_struct用於描述一段位址,linux提供了/proc/pid/maps介面,我們可以通過該介面查詢某程序的虛擬位址段:
linux # cat /proc/$$/maps
00400000 - 00486000 r-xp 00000000 08:02 18104 /bin/bash
00586000 - 00586000 rw-p 00086000 08:02 18104 /bin/bash
0058b000 - 0073b000 rw-p 0058b000 00:00 0 [heap]
2b7c1ff67000 - 2b7c1ff82000 r-xp 00000000 08:02 12969 /lib64/ld-2.4.so
……7fff8ab2d000 - 7fff8ab43000 rw-p 7fff8ab2d000 00:00 0 [stack]
ffffffffff600000 - ffffffffffe00000 ---p 00000000 00:00 0 [vdso]
c庫中的malloc底層通過mmap或brk實現記憶體申請。mmap可用於關聯檔案到程序的虛擬位址空間,也可用於申請匿名位址空間。
void *mmap( void *addr, size_t length, int prot, int flags, int fd, off_t offset);
若指明fd就是關聯檔案到虛擬位址空間,沒有指明就是申請匿名位址空間。
brk呼叫只是增加heap這一段虛擬記憶體空間,sbrk用於實際的記憶體申請。
reference: chapter 15 - the process address space, linux kernel development.3rd.edition
程序位址空間
這篇文章應該不能說是原創的,這裡的記錄都是我通過閱讀整理來的,並沒有太多的自己的想法。資料 現代作業系統 之所以去了解位址空間也是因為在學習dll的時候看到要將dll對映到程式的位址空間,不甚明了所以去查詢相關的資料。位址空間其實很好理解 當然針對早期的機器 早期的機器是沒有ram,rom,cach...
程序位址空間
kernel筆記 程序位址空間 2013 09 03 09 53 49 分類 linux 下圖是x86 64下linux程序的預設記憶體布局形式 下面逐一分析以上各個位址段的含義。text 段 段,從虛擬記憶體位址00400000開始,使用pmap 可以檢視到,這個位址是固定的 linux pmap...
程序位址空間
程序位址空間 1.可執行檔案 的記憶體對映,稱為 段 2.可執行檔案的已初始化全域性變數的記憶體對映,稱為資料段 3.包含未初始化的全域性變數,也就是bss段的零頁的記憶體對映 4.用於程序使用者控制項棧的零頁的記憶體對映 5.任何記憶體對映檔案 6.任何共享記憶體段 7.任何匿名的記憶體對映,比如...