天天看點

C/C++程式編譯流程(預處理->編譯->彙編->連結)

程式的基本流程如圖:

1. 預處理

預處理相當于根據預處理指令組裝新的C/C++程式。經過預處理,會産生一個沒有宏定義,沒有條件編譯指令,沒有特殊符号的輸出檔案,這個檔案的含義同原本的檔案無異,隻是内容上有所不同。

讀取C/C++源程式,對其中的僞指令(以#開頭的指令)進行處理

①将所有的“#define”删除,并且展開所有的宏定義

②處理所有的條件編譯指令,如:“#if”、“#ifdef”、“#elif”、“#else”、“endif”等。這些僞指令的引入使得程式員可以通過定義不同的宏來決定編譯程式對哪些代碼進行處理。預編譯程式将根據有關的檔案,将那些不必要的代碼過濾掉。 

③處理“#include”預編譯指令,将被包含的檔案插入到該預編譯指令的位置。
           

(注意:這個過程可能是遞歸進行的,也就是說被包含的檔案可能還包含其他檔案)

删除所有的注釋

添加行号和檔案名辨別。

以便于編譯時編譯器産生調試用的行号資訊及用于編譯時産生的編譯錯誤或警告時能夠顯示行号

保留所有的#pragma編譯器指令

2. 編譯

将預處理完的檔案進行一系列詞法分析、文法分析、語義分析及優化後,産生相應的彙編代碼檔案。

3. 彙編

将編譯完的彙編代碼檔案翻譯成機器指令,并生成可重定位目标程式的.o檔案,該檔案為二進制檔案,位元組編碼是機器指令。

彙編器是将彙編代碼轉變成機器可以執行的指令,每一個彙編語句幾乎都對應一條機器指令。是以彙編器的彙編過程相對于編譯器來講比較簡單,它沒有複雜的文法,也沒有語義,也不需要做指令優化,隻是根據彙編指令和機器指令的對照表一一翻譯即可。

4. 連結

通過連結器将一個個目标檔案(或許還會有庫檔案)連結在一起生成一個完整的可執行程式。

由彙程式設計式生成的目标檔案并不能立即就被執行,其中可能還有許多沒有解決的問題。
           

例如,某個源檔案中的函數可能引用了另一個源檔案中定義的某個符号(如變量或者函數調用等);在程式中可能調用了某個庫檔案中的函數,等等。所有的這些問題,都需要經連結程式的處理方能得以解決。

連結程式的主要工作就是将有關的目标檔案彼此相連接配接,也就是将在一個檔案中引用的符号同該符号在另外一個檔案中的定義連接配接起來,使得所有的這些目标檔案成為一個能夠被作業系統裝入執行的統一整體。
           

至此,大緻經過這幾個步驟,一個完整的可執行程式産生了。

原文出處:

http://www.cnblogs.com/Lynn-Zhang/p/5377024.html

繼續閱讀