本文討論了C程序的完整編譯過程,分別講述了預(yù)處理、編譯、匯編、鏈接各階段完成的編譯任務(wù)。然后通過一個編譯實例,探討了各階段輸出的文件。
編譯和鏈接
前面了解C程序結(jié)構(gòu),也編寫了第一個C程序源代碼,但計算機并不能直接執(zhí)行C程序源代碼。因為C語言是高級語言,計算機不能識別高級語言編寫的代碼,還需要把寫好的C程序源代碼轉(zhuǎn)換為計算機能識別的機器語言代碼,這個過程稱為C程序的編譯過程。編譯過程如圖1-7所示。
圖 1-7 C程序編譯過程
從圖1-7可以看出,C程序編譯過程分為四個階段:第一階段是預(yù)處理階段;第二階段是編譯階段;第三階段是匯編階段;第四階段是鏈接階段。執(zhí)行這四個階段的程序(預(yù)處理器、編譯器、匯編器、和鏈接器)一起構(gòu)成了C語言的編譯系統(tǒng)。
預(yù)處理階段:預(yù)處理階段主要用于處理源文件中的預(yù)處理指令,并根據(jù)指令對源代碼進行修改和補充。例如:“#include”指令將頭文件的內(nèi)容補充到源文件內(nèi);“#define”指令用于宏定義,通過宏定義可以進行條件編譯和內(nèi)容替換。
編譯階段:編譯階段主要用于對預(yù)處理后的文件進行詞法和語法分析,并將其翻譯成與源代碼等價的匯編代碼。
匯編階段:匯編階段將編譯輸出的匯編代碼轉(zhuǎn)換為機器代碼,機器代碼也稱為目標代碼,該代碼與計算機硬件相關(guān)。
鏈接階段:鏈接階段將多個目標代碼文件、函數(shù)庫文件鏈接成可執(zhí)行文件。
**編譯實例 **
下面以《C程序結(jié)構(gòu)》中的面積計算器程序為例,在Ubuntu系統(tǒng)下使用GCC編譯器,對面積計算器程序進行編譯和鏈接。
面積計算器程序可以計算長方形、正方形、平行四邊形和三角形的面積,它由main.c、rectangle.c、square.c、paraller.c、triangle.c、area.h五個源文件和一個頭文件構(gòu)成,area.h頭文件描述了面積計算函數(shù)的原型。面積計算器程序結(jié)構(gòu)如圖所示。程序代碼請參見《C程序結(jié)構(gòu)》。
圖 1-8 面積計算器程序結(jié)構(gòu)
預(yù)處理階段
預(yù)處理階段主要處理C程序源文件內(nèi)的預(yù)處理指令,如#include指令、宏定義等。預(yù)處理階段會對所有的C源文件進行預(yù)處理,預(yù)處理后的文件也是文本文件,可以使用文本編輯器打開,不過其文件大小要比C源文件大的多,因為預(yù)處理后的文件會將#include指令引入的頭文件寫入到C源文件內(nèi)。面積計算器的main.c文件使用了#include指令,主要代碼如下:
//引入C語言標準輸入輸出函數(shù)庫
//stdio.h是標準輸入輸出函數(shù)庫的頭文件
#include
//引入面積計算器函數(shù)頭文件
include "area.h"
void main()
{
……
}
GCC編譯器提供了如下命令對C源文件進行預(yù)處理:
gcc -E C源文件-o [預(yù)處理后文件]
例如:
gcc -E main.c -o main.i
對main.c文件進行預(yù)處理,預(yù)處理后的文件為main.i。執(zhí)行上述預(yù)處理命令時,需要gcc能夠找到main.c文件。
main.c預(yù)處理后文件main.i要比main.c大很多,感興趣的同學(xué)可以實際操作后,用文本編輯器打開main.i文件,看看里面的內(nèi)容。
面積計算器程序所有C源文件預(yù)處理后的文件列表,從列表中可以看出,除了main.c文件外,其它預(yù)處理后文件和C源文件大小變化不大,這是因為這些C源文件沒有包含頭文件。
編譯階段
編譯階段將預(yù)處理后文件轉(zhuǎn)換為匯編代碼,編譯后的匯編代碼也是文本文件,可以直接使用文本編輯器打開匯編代碼。
GCC編譯器提供了如下命令對預(yù)處理后文件進行編譯:
gcc -E 預(yù)處理后文件-o [匯編代碼]
例如:
gcc -S square.i -o square.s
對square.i文件進行編譯,編譯后的文件為square.s。執(zhí)行上述預(yù)處理命令時,需要gcc能夠找到square.i文件。
編譯后匯編代碼如下圖所示:
匯編階段
匯編階段將匯編代碼轉(zhuǎn)換為機器代碼(機器可以直接執(zhí)行的CPU指令),轉(zhuǎn)換程序也稱為匯編程序。由于不同CPU架構(gòu)的計算機,其提供的指令集不同,支持運行的機器代碼也不同,因此,要運行在不同CPU架構(gòu)的計算機上,就需要運行支持該CPU架構(gòu)的匯編程序。例如IBM-PC機采用了Intel X86系列處理器,單片機一般采用ARM架構(gòu)的系列處理器,如果要讓編寫的匯編程序運行在IBM-PC機上,就需要調(diào)用支持IBM-PC指令集的匯編程序,如果要讓編寫的匯編程序運行在ARM架構(gòu)的計算機上,就需要調(diào)用支持ARM指令集的匯編程序。
匯編階段輸出的文件為目標文件,它是二進制格式,不能使用文本編輯器瀏覽文件內(nèi)容。GCC編譯器提供了如下命令對C源文件進行預(yù)處理:
gcc -c 匯編代碼文件-o [目標文件]
例如:
gcc -c rectangle.s -o rectangle.o
對rectangle.s文件進行匯編,匯編后的文件為rectangle.o。執(zhí)行上述預(yù)處理命令時,需要gcc能夠找到rectangle.s文件。
匯編階段執(zhí)行后,面積計算器程序文件列表如下圖所示:
鏈接階段
面積計算器程序在匯編階段輸出了main.o、square.o、triangle.o、rectangle.o、paraller.o目標文件,在鏈接階段需要將這些目標文件鏈接為可執(zhí)行文件。鏈接使用ld命令,ld是GCC提供的鏈接器,將目標文件與函數(shù)庫鏈接為可執(zhí)行程序或庫文件。不過ld鏈接器一般不獨立使用,由GCC自動調(diào)用鏈接器。
輸入下面的命令:
gcc main.c paraller.c rectangle.c square.c triangle.c
即可完成面積計算器程序的編譯和鏈接。
本文小結(jié)
通過以上分析可知,C程序的編譯過程要經(jīng)過預(yù)處理、編譯、匯編和鏈接四個階段。令人欣慰的是C程序編譯工具都提供了一次性編譯和鏈接命令,編譯器會自動執(zhí)行這四個階段,不需要開發(fā)者的參與。
-
編譯
+關(guān)注
關(guān)注
0文章
676瀏覽量
33743 -
C程序
+關(guān)注
關(guān)注
4文章
255瀏覽量
36596 -
匯編代碼
+關(guān)注
關(guān)注
0文章
24瀏覽量
7621 -
宏定義
+關(guān)注
關(guān)注
0文章
51瀏覽量
9179
發(fā)布評論請先 登錄
使用scons編譯時,需要怎么做才能輸出gcc的完整編譯信息呢?
使用scons編譯時,我需要怎么做才能輸出gcc的完整編譯信息呢?
C語言實現(xiàn)運算器的原理完整編程代碼
GCC編譯C語言程序的過程是怎么樣的
單片機C程序編譯、執(zhí)行過程資料下載

TKScope對LPC1700系列芯片的完整編程和加密方法

TKScope對LPC1300系列芯片的完整編程和加密方法

TKScope對AT91SAM7X256的完整編程和加密方法

RX族C/C++編譯程序、匯編程序、優(yōu)化連接編輯程序 編譯程序包 用戶手冊 Rev.1.00

SuperHTM RISC引擎C/C++編譯程序、匯總程序、優(yōu)化連接編譯程序 編譯程序包V.9.01 用戶手冊

評論