資源描述:
《gcc編譯的四個(gè)階段》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、gcc的編譯流程分為四個(gè)步驟,分別為:?預(yù)處理(Pre-Processing)?編譯(Compiling)?匯編(Assembling)?鏈接(Linking)下面就具體來查看一下gcc是如何完成四個(gè)步驟的。hello.c源代碼#includeintmain(){??printf("HelloWorld!");??return0;}(1)預(yù)處理階段在該階段,編譯器將上述代碼中的stdio.h編譯進(jìn)來,并且用戶可以使用gcc的選項(xiàng)”-E”進(jìn)行查看,該選項(xiàng)的作用是讓gcc在預(yù)處理結(jié)束后停止編譯過
2、程?!渡钊肜斫庥?jì)算機(jī)系統(tǒng)》中是這么說的:???預(yù)處理器(cpp)根據(jù)以字符#開頭的命令(directives),修改原始的C程序。如hello.c中#include指令告訴預(yù)處理器讀系統(tǒng)頭文件stdio.h的內(nèi)容,并把它直接插入到程序文本中去。結(jié)果就得到另外一個(gè)C程序,通常是以.i作為文件擴(kuò)展名的。??注意:???????Gcc指令的一般格式為:Gcc[選項(xiàng)]要編譯的文件[選項(xiàng)][目標(biāo)文件]其中,目標(biāo)文件可缺省,Gcc默認(rèn)生成可執(zhí)行的文件名為:編譯文件.out[gan@localhostgcc]
3、#gcc–Ehello.c–ohello.i選項(xiàng)”-o”是指目標(biāo)文件,”.i”文件為已經(jīng)過預(yù)處理的C原始程序。以下列出了hello.i文件的部分內(nèi)容:typedefint(*__gconv_trans_fct)(struct__gconv_step*,????????struct__gconv_step_data*,void*,????????__constunsignedchar*,????????__constunsignedchar**,????????__constunsignedchar*,unsign
4、edchar**,????????size_t*);…#2"hello.c"2intmain(){printf("HelloWorld!");return0;}由此可見,gcc確實(shí)進(jìn)行了預(yù)處理,它把”stdio.h”的內(nèi)容插入到hello.i文件中。(2)編譯階段接下來進(jìn)行的是編譯階段,在這個(gè)階段中,Gcc首先要檢查代碼的規(guī)范性、是否有語法錯(cuò)誤等,以確定代碼的實(shí)際要做的工作,在檢查無誤后,Gcc把代碼翻譯成匯編語言。用戶可以使用”-S”選項(xiàng)來進(jìn)行查看,該選項(xiàng)只進(jìn)行編譯而不進(jìn)行匯編,生成匯編代碼。匯編語言是非常
5、有用的,它為不同高級(jí)語言不同編譯器提供了通用的語言。如:C編譯器和Fortran編譯器產(chǎn)生的輸出文件用的都是一樣的匯編語言。[gan@localhostgcc]#gcc–Shello.i–ohello.s以下列出了hello.s的內(nèi)容,可見Gcc已經(jīng)將其轉(zhuǎn)化為匯編了,感興趣的讀者可以分析一下這一行簡單的C語言小程序是如何用匯編代碼實(shí)現(xiàn)的。????.file??"hello.c"????.section???.rodata????.align4.LC0:????.string????"HelloWorld!"???
6、?.text.globlmain????.typemain,@functionmain:????pushl%ebp????movl%esp,%ebp????subl$8,%esp????andl$-16,%esp????movl$0,%eax????addl$15,%eax????addl$15,%eax????shrl$4,%eax????sall$4,%eax????subl%eax,%esp????subl$12,%esp????pushl$.LC0????callputs????addl$16,%esp?
7、???movl$0,%eax????leave????ret????.size??main,.-main????.ident"GCC:(GNU)4.0.020050519(RedHat4.0.0-8)"????.section???.note.GNU-stack,"",@progbits(3)匯編階段匯編階段是把編譯階段生成的”.s”文件轉(zhuǎn)成目標(biāo)文件,讀者在此可使用選項(xiàng)”-c”就可看到匯編代碼已轉(zhuǎn)化為”.o”的二進(jìn)制目標(biāo)代碼了。如下所示:[gan@localhostgcc]#gcc–chello.s–ohello
8、.o(4)鏈接階段在成功編譯之后,就進(jìn)入了鏈接階段。在這里涉及到一個(gè)重要的概念:函數(shù)庫。讀者可以重新查看這個(gè)小程序,在這個(gè)程序中并沒有定義”printf”的函數(shù)實(shí)現(xiàn),且在預(yù)編譯中包含進(jìn)的”stdio.h”中也只有該函數(shù)的聲明,而沒有定義函數(shù)的實(shí)現(xiàn),那么,是在哪里實(shí)現(xiàn)”printf”函數(shù)的呢?最后的答案是:系統(tǒng)把這些函數(shù)實(shí)現(xiàn)都被做到名為libc.so.6的庫文件中去了,在沒