2009-12-27 22 views
1

對不起,如果這個問題太瑣碎了!衆所周知,最終的可執行文件不會爲映像中未初始化的數據分配空間。但是我想知道,在.bss中符號的引用是如何解決的?如何在最終圖像中解析.bss的變量?

目標文件是否僅包含.bss這些變量的地址some where else not NOT space for them?如果是這樣,這些解析的地址在哪裏存儲?

例如,如果在C模塊中,我有類似下面的全局變量 -

int x [10]; char chArray [100];

以上變量的空間可能不存在於圖像中,但如何引用它們?他們的地址在哪裏解決?

在此先感謝! /MS

回答

2

.bss符號像編譯器(或彙編器)生成的任何其他符號一樣得到解決。通常這通過在「部分」中放置相關的符號來工作。例如,編譯器可能會將程序代碼放在名爲「.text」的部分(出於歷史原因;-),在名爲「.data」的部分中初始化數據,以及在名爲「.bss」的部分中單元化數據。

例如:

int i = 4; 
int x[10]; 
char chArray[100]; 

int main(int argc, char**argv) 
{ 
} 

產生(用gcc -S):

.file "test.c" 
.globl i 
    .data 
    .align 4 
    .type i, @object 
    .size i, 4 
i: 
    .long 4 
    .text 
.globl main 
    .type main, @function 
main: 
    leal 4(%esp), %ecx 
    andl $-16, %esp 
    pushl -4(%ecx) 
    pushl %ebp 
    movl %esp, %ebp 
    pushl %ecx 
    subl $4, %esp 
    addl $4, %esp 
    popl %ecx 
    popl %ebp 
    leal -4(%ecx), %esp 
    ret 
    .size main, .-main 
    .comm x,40,32 
    .comm chArray,100,32 
    .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)" 
    .section  .note.GNU-stack,"",@progbits 

的。數據指令通知彙編放置i的數據部分中,」。長4"給它它的初始值。當文件被組裝時,我將在數據部分的偏移量0處定義。

.text指令將把main放置在.text節中,同樣偏移量爲零。

這個例子有趣的是x和chArray是使用.comm指令定義的,而不是直接放在.bss中。兩者都只有一個大小,而不是抵消(還)。

當鏈接器獲取目標文件時,它通過組合具有相同名稱的所有部分並相應地調整符號偏移將它們鏈接在一起。它也爲每個部分提供了一個絕對的地址來加載它。

將由.comm指令定義的符號組合在一起(如果存在多個具有相同名稱的定義)並放置在.bss節中。在這一點上,他們得到了他們的地址。

+0

+1無法解釋更好! 雖然所有這些都是架構相關的,雖然我不知道一個例子,但所有的.bss地址都可以相對於硬件寄存器組成 - 所以實際地址只能解析在運行時。 – James 2009-12-27 16:04:34

+0

@Autopulated:好點。我實際上實現了一個C編譯器,它的確如此:它使用X索引寄存器指向.bss區域以獲取與位置無關的數據。 – 2009-12-27 16:17:12

+0

謝謝:-)。因此,如果得到它,那麼一旦所有的.comm指令被合併,並且這些解析的地址在它們被引用的任何地方被修補(變量的.bss +偏移類型),則.bss將得到它的符號解析。在運行時分配.bss基址。對? – 2009-12-27 17:38:06