C語言的預處理、編譯、彙編、鏈接 轉

一、預處理

預處理指令的執行主要包含下列事情:

1.頭文件的包含

2.註釋的刪除

3.宏定義的替換

4.條件編譯的選擇

指令:gcc  -E test.c -o test.i    

/* 調用的是預處理器cpp, -E:只進行預處理操作,-o:輸出到<文件> , .i表示產生的臨時文件 Intermediate */

二、編譯

編譯之前,C語言編譯器會進行詞法分析、語法分析(-fsyntax-only)。

在確認所有的指令都符合語法規則之後,將其翻譯成相應的後綴爲S的彙編文件。

指令:gcc -S test.i -o test.S  

/* 調用的是編譯器ccl, -S:編譯到彙編語言,不進行彙編和鏈接, .S:表示彙編文件,注意於.s彙編文件的區別 */


.s :彙編語言源程序;彙編

.S:彙編語言源程序;預處理,彙編

小寫的s文件,在後期階段不在進行預處理操作,所以我們不能在這裏面寫預處理的語句在裏面

大寫的S文件,還會進行預處理、彙編等操作,所以我們可以在這裏面加入預處理的命  

三、彙編

在編譯與彙編之間,編譯器通常還會做一些優化操作。

彙編過程實際上指把彙編語言代碼翻譯成目標機器指令的過程

指令:gcc -c test.S -o test.o

/* 調用的是彙編器as,-c:編譯、彙編到目標代碼,不進行鏈接, .o表示產生目標文件, object

此時用file查看test.o文件的類型爲ELF 32-bit LSB relocatable類型,這是可重定位的格式 */

四、鏈接

由彙編程序生成的目標文件並不能立即就被執行,其中可能還有許多沒有解決的問題。例如,某個源文件中的函數可能引用了另一個 源文件中定義的某個符號(如變量或者函數調用等);在程序中可能調用了某個庫文件中的函數等等。所有的這些問題,都需要經鏈接程序的處理方能得以解決。

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

函數庫一般分爲靜態庫和動態庫兩種。靜態庫是指編譯鏈接時,把庫文件的代碼全部加入到可執行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了。其後綴名一般爲”.a”。動態庫與之相反,在編譯鏈接時並沒有把庫文件的代碼加入到可執行文件中,而是在程序執行時由運行時鏈接文件加載庫,這樣可以節省系統的開銷。動態庫一般後綴名爲”.so”,如前面所述的libc.so.6就是動態庫。gcc在編譯時默認使用動態庫。

指令:gcc test.o -o test

/* 用file查看test文件類型爲:ELF 32-bit LSB executable,這是可以被執行的文件格式 */


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章