bss section 的觀念:執行時期的結構說明

jollen 發表於 December 17, 2006 10:02 PM

目前已經了解到:.bss section 在 linking view 時是不佔檔案長度的,在 execution view 時,根據其長度來佔用記憶體大小。

關於 .bss section 的結構,其實一張圖就夠了。直接切入重點吧!

前言

先重新編譯 bss.c 範例:

# gcc -g -o bss bss.c
# ./bss
.bss section starts at 0x8049588
foo is 0.
foo is 12345.
.bss section starts at 0x8049588

依照先前日記的說明,.bss section 的長度為 12 bytes。無論程式是否有 uninitialized data,process 一定會有 .bss section,並且 .bss section 的長度至少為 4 bytes(IA32),第一筆資料是 "completed.1",該筆資料紀錄 .bss section 的起啟位址。

另外,在「linker script」裡,定義了一個叫 "__bss_start" 的符號,此符號才是紀錄 .bss section 的真正起始位址。不過,在此先不討論這個部份。

Process 的 .bss section 結

Process 的 .bss section 佔用的記憶體大小,是根據 .bss section 的長度,在執行時期為每一筆 uninitialized data 保留下來的。其結構如下圖所示,我們以 bss.c 的範例來說明。

bss_section_structure.jpg

圖 .bss section 結構

由圖可以知道,範例的 .bss section 其 start address 為 0x8049584,這是直接查詢 .bss section 裡的 "completed.1" 符號得知的。'completed.1' 的 address 可利用 nm 查詢:

# nm -v bss|grep 'completed.1'
08049584 b completed.1

由此了解,.bss section 真正的 start address 應該是 'completed.1';不過,若把第一筆資料的 start address 當做 .bss section 的 start address 其實也無妨,或者說這是 .bss section「放 data」的 start address。

利用 gdb 來觀察

# gdb ./bss
...
(gdb) disassemble 0x8049588
Dump of assembler code for function foo:
0x08049588 <foo+0>: add %al,(%eax)
0x0804958a
<foo+2>: add %al,(%eax)
End of assembler dump.
(gdb) disassemble 0x8049584
Dump of assembler code for function completed.1:
0x08049584 <completed.1+0>: add %al,(%eax)
0x08049586 <completed.1+2>: add %al,(%eax)

(gdb) disassemble 0x804958c
Dump of assembler code for function bar:
0x0804958c <bar+0>: add %al,(%eax)
0x0804958e <bar+2>: add %al,(%eax)

End of assembler dump.

Also See

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw