前言
C語(yǔ)言中從源代碼到二進(jìn)制程序都經(jīng)歷了那些過(guò)程?
什么是gcc
gcc的全稱是GNU Compiler Collection榆俺,它是一個(gè)能夠編譯多種語(yǔ)言的編譯器。最開(kāi)始gcc是作為C語(yǔ)言的編譯器(GNU C Compiler)舒萎,現(xiàn)在除了c語(yǔ)言藐鹤,還支持C++、java登疗、Pascal等語(yǔ)言排截。gcc支持多種硬件平臺(tái)嫌蚤。
示例
預(yù)處理(Preprocessing)
預(yù)處理用于將所有#include頭文件以及宏定義替換成其真正的內(nèi)容,預(yù)處理之后得到的仍然是C代碼文件断傲,但是行數(shù)會(huì)變多脱吱。gcc的預(yù)處理是通過(guò)cpp預(yù)處理器來(lái)完成的,示例如下:
gcc -E hello.c -o hello.i
或者直接調(diào)用cpp命令
cpp hello.c -o hello.i
預(yù)處理過(guò)程
1.宏定義指令:將所有的#define刪除认罩,并且展開(kāi)所有的宏定義
2.條件編譯指令:處理所有的條件預(yù)編譯指令箱蝠,比如#if #ifdef #elif #else #endif等
3.頭文件包含指令:處理#include 預(yù)編譯指令,將被包含的文件插入到該預(yù)編譯指令的位置
4.特殊符號(hào)指令:預(yù)編譯器可研識(shí)別一些特殊的符號(hào)垦垂,例如:刪除所有注釋 “//”和”/* */”
5.添加行號(hào)和文件標(biāo)識(shí)宦搬,以便編譯時(shí)產(chǎn)生調(diào)試用的行號(hào)及編譯錯(cuò)誤警告行號(hào)
6.保留所有的#pragma編譯器指令,因?yàn)榫幾g器需要使用它們
編譯(Compilation)
編譯過(guò)程就是把預(yù)處理完的文件進(jìn)行一系列的詞法分析劫拗,語(yǔ)法分析床三,語(yǔ)義分析及優(yōu)化后生成相應(yīng)的匯編代碼的過(guò)程
gcc -S hello.i -o hello.s
匯編(Assemble)
匯編過(guò)程將編譯后的匯編代碼轉(zhuǎn)換成機(jī)器可以執(zhí)行的命令,即機(jī)器碼(machine code)杨幼,每一個(gè)匯編語(yǔ)句幾乎都對(duì)應(yīng)一條機(jī)器指令撇簿。根據(jù)匯編指令和機(jī)器指令的對(duì)照表一一翻譯即可,這一步會(huì)為每一個(gè)源文件產(chǎn)生一個(gè)文件叫做目標(biāo)文件差购,是二進(jìn)制格式四瘫。gcc匯編過(guò)程通過(guò)as命令完成,示例如下:
gcc -c hello.s -o hello.o
或者直接調(diào)用cpp命令
as hello.s -o hello.o
鏈接(Linking)
通過(guò)調(diào)用鏈接器ld將程序運(yùn)行需要的一大堆目標(biāo)文件欲逃,以及所依賴的其它庫(kù)文件進(jìn)行鏈接找蜜,最后生成可執(zhí)行文件。 鏈接的核心是把各個(gè)模塊之間相互引用的部分處理好稳析,使得各個(gè)模塊之間能夠正確地銜接洗做。鏈接又會(huì)根據(jù)鏈接對(duì)象靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的不同,分為靜態(tài)鏈接和動(dòng)態(tài)鏈接彰居。靜態(tài)鏈接是在鏈接階段把靜態(tài)庫(kù)加到可執(zhí)行程序中的诚纸,相當(dāng)于替換了引用。動(dòng)態(tài)鏈接是在鏈接階段只是加入引用陈惰,真正在程序運(yùn)行的時(shí)候畦徘,系統(tǒng)動(dòng)態(tài)加載動(dòng)態(tài)庫(kù)內(nèi)容到內(nèi)存中。
靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)都是二進(jìn)制文件抬闯,存放了函數(shù)的實(shí)現(xiàn)井辆,只是使用的方式不同。
gcc hello.o -o hello
結(jié)語(yǔ)(Linking)
經(jīng)過(guò)以上分析溶握,我們發(fā)現(xiàn)編譯過(guò)程并不像想象的那么簡(jiǎn)單杯缺,而是要經(jīng)過(guò)預(yù)處理、編譯睡榆、匯編萍肆、鏈接袍榆。盡管我們平時(shí)使用gcc命令的時(shí)候沒(méi)有關(guān)心中間結(jié)果,但每次程序的編譯都少不了這幾個(gè)步驟匾鸥。也不用為上述繁瑣過(guò)程而煩惱蜡塌,因?yàn)槟闳匀豢梢裕?/p>
gcc hello.c -o hello #編譯
./hello #執(zhí)行