C語言編譯與鏈接


程序由源文件到可執行文件,一般經過預處理(Prepressing)、編譯(Compilation)、匯編(Assembly)和鏈接(Linking)這四個階段。如下圖表示

這里寫圖片描述

預處理

預處理過程主要處理那些源代碼文件只能夠的以”#”開始的預編譯指令。比如“#include”、“#define”等,主要處理規則如下:
(1)將所有的“#define“刪除,並且展開所有的宏定義;
(2)處理所有條件預編譯指令,比如”#if“、”#ifdef“、”#elif“、”#else“、#endif;
(3)處理”#include“預編譯指令,將被包含的文件插入到該預編譯指令的位置。注意:這個過程是遞歸進行的,也就是說被包含的文件可能還包含其他文件;
(4)刪除所有的注釋”//“和”、”/**/“;
(5)添加行號和文件名標識,比如#2 “test.c” 2,以便於編譯時編譯器產生調試用的行號信息及用於編譯時產生編譯錯誤或警告時能夠顯示行號;
(6)保留所有的#pragma編譯器指令,因為編譯器需要使用它們;

編譯

編譯過程就是把預處理完的文件進行一系列的詞法分析、語法分析、語義分析以及優化,在確認所有的指令都符合語法規則之后,將其翻譯成等價的中間代碼表示或匯編代碼,這個過程往往是我們所說的整個程序的構建的核心部分,也是最復雜的部分之一。

匯編

匯編實際上指匯編器(as)把匯編語言代碼翻譯成目標機器指令的過程。目標文件中所存放的也就是與源程序等效的目標的機器語言代碼。目標文件由段組成。通常一個目標文件中至少有兩個段:

代碼段:該段中所包含的主要是程序的指令。該段一般是可讀和可執行的,但一般卻不可寫。
數據段:主要存放程序中要用到的各種全局變量或靜態的數據。一般數據段都是可讀,可寫,可執行的。

鏈接

由匯編程序生成的目標文件並不能立即就被執行,其中可能還有許多沒有解決的問題。

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

  鏈接程序的主要工作就是將有關的目標文件彼此相連接,也即將在一個文件中引用的符號同該符號在另外一個文件中的定義連接起來,使得所有的這些目標文件成為一個能夠誒操作系統裝入執行的統一整體。

 我們在linux使用的gcc編譯器便是把以上的幾個過程進行捆綁,使用戶只使用一次命令就把編譯工作完成,這的確方便了編譯工作,但對於初學者了解編譯過程就很不利了,下圖便是gcc代理的編譯過程:
 這里寫圖片描述

參考自:
1.第二章——編譯和鏈接
2.C 編譯、鏈接、加載
3.C語言的編譯鏈接過程的介紹



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com