我想了解更多關於可執行文件的「常見」部分,並且我注意到,在編譯代碼上執行objdump
時,我可以看到變量僅放置在對象文件(*.o
)上的通用代碼中,而不是可執行文件中。爲什麼公共部分變量只顯示在目標文件中而不是可執行文件?
這是爲什麼?
//test.c
int i[1000];
int main(){return 0;}
構建命令:
> gcc -g0 -fcommon -c test.c
> gcc -g0 -fcommon test.c
objdump
顯示i
在符號表中的共同部分:
> objdump -x test.o
...
SYMBOL TABLE:
...
00000fa0 O *COM* 00000020 i
除非我的可執行文件運行它:
> objdump -x a.out
...
SYMBOL TABLE:
...
0804a040 g O .bss 00000fa0 i
如果我使用-fno-common
標誌重建目標文件,它將顯示在.bss
段中,就像它在可執行文件中所做的一樣。最終的可執行文件沒有這個「常見」部分?
好的......那麼共同部分是什麼意思呢?同時使用'fcommon'和'fno-common'的最終結果是未初始化的變量以可執行文件的.bss段結束;或者它存在的原因與你寫''[典型的]''相同?這意味着也有例外 – Mike 2013-02-12 19:32:09
@Mike但是編譯器並不知道這個 - 它是連接器的工作,以解決這個問題。對於提供.bss段的目標(和可執行格式),bss段通常在運行時分配和初始化。在沒有這種能力的目標上,通用部分最終在可執行文件中,如果你有一個10Mb的全局數組,那麼你的可執行文件最終會變成10Mb。這也允許您編寫自己的鏈接器腳本,並將這些常用部分放在您想要的地方。 -fno-common有其他用途,但是gcc手冊頁解釋了它。 – nos 2013-02-12 19:35:28
我說「一個典型」,因爲可以在某些體系結構中添加額外的部分,並且這些部分也可以分配所有方式的屬性。並不是所有的編譯器,鏈接器等都可以支持這個功能,'gcc'能夠在大量系統上運行,並且擁有大量的操作系統架構。我不希望有人在操作系統glurf上指出,在鏈接器X中,有部分叫做......等。 – 2013-02-12 19:41:55