第二章
編譯和鏈接
這章比較籠統,都是概念,熟悉基本流程的人,建議不看。
記錄一些基本流程
拿GCC來說
用GCC編譯鏈接生成可執行文件的過程分為下面4個步驟
Prepressing,Compilation,Assembly,Linking
Prepressing 預處理
從.c -> .i (gcc -E)
主要是處理,前綴為‘#’的語句
define的直接替換
對define這種,從我觀察應該是這樣
對源文件類似.c直接掃描 看到define的符號直接加到表中
然后在替換的時候會做遞歸檢查,直到符號是最終定義。
所以這個與define的順序沒有太大關系了,只要不循環嵌套
類似這種
#define M (N + 1)
#define N 2
這種在用到M的時候,會先替換成 (N + 1)但是發現替換的表達式中還有未決symbol,那么
就再進行替換 (2 + 1)
表中并不會直接寫成 M (2 + 1),至少我看到的GCC行為是這樣。
include的也是直接導入
另外預編譯選項 #ifdef 之類的會處理掉,刪掉所有注釋
#pragma是要被保留給編譯器的,這是編譯器選項,例如 pragma pack是用來指定字節對齊標準的
Compilation 編譯
從 .i -> .s (gcc -S)
現在的GCC版本都把預編譯和編譯做到了一個可執行程序中 -> ccl
編譯的主要過程
掃描,語法分析,語義分析,源代碼優化,代碼生成,目標代碼優化
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的時候由于每個源文件都是單獨編譯,那么必須處理一些外來的symbol
包括函數和全局變量