第二章
編譯和鏈接
這章比較籠統(tǒng),都是概念,熟悉基本流程的人,建議不看。
記錄一些基本流程
拿GCC來(lái)說(shuō)
用GCC編譯鏈接生成可執(zhí)行文件的過(guò)程分為下面4個(gè)步驟
Prepressing,Compilation,Assembly,Linking
Prepressing 預(yù)處理
從.c -> .i (gcc -E)
主要是處理,前綴為‘#’的語(yǔ)句
define的直接替換
對(duì)define這種,從我觀(guān)察應(yīng)該是這樣
對(duì)源文件類(lèi)似.c直接掃描 看到define的符號(hào)直接加到表中
然后在替換的時(shí)候會(huì)做遞歸檢查,直到符號(hào)是最終定義。
所以這個(gè)與define的順序沒(méi)有太大關(guān)系了,只要不循環(huán)嵌套
類(lèi)似這種
#define M (N + 1)
#define N 2
這種在用到M的時(shí)候,會(huì)先替換成 (N + 1)但是發(fā)現(xiàn)替換的表達(dá)式中還有未決symbol,那么
就再進(jìn)行替換 (2 + 1)
表中并不會(huì)直接寫(xiě)成 M (2 + 1),至少我看到的GCC行為是這樣。
include的也是直接導(dǎo)入
另外預(yù)編譯選項(xiàng) #ifdef 之類(lèi)的會(huì)處理掉,刪掉所有注釋
#pragma是要被保留給編譯器的,這是編譯器選項(xiàng),例如 pragma pack是用來(lái)指定字節(jié)對(duì)齊標(biāo)準(zhǔn)的
Compilation 編譯
從 .i -> .s (gcc -S)
現(xiàn)在的GCC版本都把預(yù)編譯和編譯做到了一個(gè)可執(zhí)行程序中 -> ccl
編譯的主要過(guò)程
掃描,語(yǔ)法分析,語(yǔ)義分析,源代碼優(yōu)化,代碼生成,目標(biāo)代碼優(yōu)化
Source code --Scanner--> Tokens --Parser--> Syntax Tree
--Semantic Analyzer--> Commented Syntax Tree --Source code Optimizer--> Intermediate Representation
--Code Generator--> Target Code --Code Optimizer-->Final Target Code
Assembly 匯編
從 .s -> .o (gcc -c) -->匯編器as
Linking 鏈接
ld做的事情
link的時(shí)候由于每個(gè)源文件都是單獨(dú)編譯,那么必須處理一些外來(lái)的symbol
包括函數(shù)和全局變量