我們都知道,編譯器編譯源代碼后生成的文件是目標文件,那么,目標文件與可執行文件之間有什么區別呢?其最本質的內容是什么呢?
目標文件的格式
實際上,目標文件是源代碼編譯但未鏈接的中間文件(windows的.obj文件和linux的.o文件).它與可執行文件的內容與結構十分相似,從廣義上二者的格式幾乎一樣。windows下,我們統稱為PE-COFF文件格式,Linux下統稱為ELF文件,其實,它們都是COFF(Common file format)的變種。
從結構上,目標文件是編譯后的可執行文件格式, 但未經過鏈接過程,缺少啟動代碼和庫例程(http://www.cnblogs.com/getyoulove/p/3674791.html)。而可執行文件涵蓋了編譯、鏈接、裝載和執行的各個方面。
目標文件內容
目標文件中包含了編譯后的機器指令代碼、數據、以及鏈接時所需的信息,如符號表、調試信息、字符串等。通常這些信息會根據屬性,以“節”(“段”)的形式存儲。通常,機器指令放在代碼段,全局變量或局部靜態變量放在數據段。代碼段常見名字有“.code”或“.text”,數據段一般命名“.data”。
Q&A
Q:總體來說,程序源代碼被編譯后主要分為兩種段:程序指令和程序數據。那么為什么要把指令和數據分開呢?
A:
- 當程序被裝載后,相對進程來說,數據是可讀寫的,而指令一般是只讀的。因此將兩者分段,可以將其分別映射到兩個虛擬區域,設置不同的權限,防止程序的指令被有意或無意改寫。
- 現代CPU的緩存一般被設計成數據緩存和指令緩存分離。兩者分離有利於提高程序局部性,提高CPU的緩存命中率。
- 最為重要的是,實現指令恭喜,尤其是在動態鏈接的系統中,可以節省大量內存。