《程式設計師的自我修養》第二章學習筆記

2022-01-12 04:30:39 字數 1975 閱讀 6005

第二章 編譯和鏈結

2.1被隱藏了的過程

我們知道,乙個程式由源**到可執行檔案往往由這幾步構成:

預處理(prepressing)-> 編譯(compilation)-> 彙編(assembly)-> 鏈結(linking)。

如圖所示,

2.1.1預編譯 

#includeint main(void

)

如上述檔案hello.c,  gcc -e hello.c -o hello.i

預編譯過程主要處理哪些源**檔案中的以 "#" 開始的預編譯指令,比如 #include,#define 等,主要處理規則如下:

1. 將所有的#define刪除,並且展開所有的巨集定義。

2. 處理所有的預編譯指令,比如 "#if" "#ifdef" "#elif" "#else" "#endif"等。

3. 處理"#include"預編譯指令,將被包含的檔案插入到該預編譯的位置。注意:這個過程是遞迴進行的,也就是說被包含的檔案可能還包含其他檔案。

4. 刪除所有的注釋 "//"  ''/* */"。

5. 新增行號和檔名標識,比如

#2"hello.c"2

,以便於編譯時編譯器產生除錯用的符號資訊及用於編譯時產生編譯錯誤或警告時能夠顯示行號

6. 保留所有的#pragma編譯器指令,因為編譯器需要用到它們。

經過預編譯後的.i檔案不包含任何巨集定義(所有的巨集都展開了),被包含的檔案也被插入到.i檔案中。

2.1.2編譯 詳情參考2.2

1,現在版本的gcc把預編譯和編譯合併成了乙個步驟,使用乙個叫做ccl的程式來完成這兩個步驟。

2,gcc只是一些後台程式的包裝,它會根據不同的引數要求去呼叫預編譯程式ccl,彙編器as,鏈結器ld。

2.1.3彙編

1,彙編器是將彙編**轉變成機器可以執行的指令,每乙個彙編語句幾乎都對應一條機器指令。

2,所以彙編器的彙編過程相對於編譯器來講比較簡單,它沒有複雜的語法,也沒有語義,也不需要做指令優化,只是根據彙編指令和機器指令的對照表一一翻譯就可以了。

3,經過預編譯、編譯和彙編直接輸出目標檔案(object file)。

4,可呼叫彙編器as來完成,  as hello.s –o hello.o

5,或者 gcc –c hello.s –o hello.o

6,也可以一步到位  gcc –c hello.c –o hello.o

2.1.4鏈結

2.2編譯器做了什麼  參考如下

2.3鏈結器的年齡比編譯器長

2.4模組拼裝---靜態鏈結

1,  人們把每個源**模組獨立編譯,然後按照需要將它們「組裝」起來,這個組裝的過程就是鏈結(linking)。

2,  鏈結的主要內容就是:把各個模組之間相互引用的部分都處理好,使得各個模組之間能夠正確的銜接。

4,  鏈結過程主要包括了:位址和空間分配(address and storage allocation),符號決議(symbol resolution)和重定位(relocation)。

5,  最基本的靜態鏈結如下圖所示,原始檔經過編譯成目標檔案(*.o /  *.obj),目標檔案和庫一起鏈結最終形成可執行檔案。

6,  假如main.c用到了另乙個模組fun.c中的food()函式。

(1)編譯mian.c時並不知道foo()的位址,所以暫時把這些呼叫foo()的指令的目標位址擱置。

(2(3

)然後將main.c中所有用到foo的指令重新修正,讓它們的目標位址為真正的foo函式的位址。

7,  位址修正的過程也叫重定位(relocation)。

8,  每個要被修正的地方叫乙個重定位入口(relocation entry)。

程式設計師的自我修養學習筆記 第二章

從原始檔到可以行檔案的過程 預處理 編譯 彙編 鏈結 第一步預編譯 gcc e hello.c o hello.i 或者 cpp hello.c hello.i 注 e 選項表示只進行預編譯 cpp是預編譯器 預編譯主要處理一 開頭的預編譯指令 將所有的 define 刪除,並且展開所有的巨集定義 ...

《程式設計師的自我修養》筆記

以下是我讀此書時作的一些筆記,當然書中還有很多值得參考的想法,就不一一枚舉了。一萬小時說法 這個說法很普遍了,它再次提醒了我如何去做乙個領域的專家。如果平均每天八小時在這個領域上,那麼一年300天 300 8 2400,保持這種學習激情在上面,五年內就可以成為專家了,我算了算自己在這個領域投入的時間...

程式設計師的自我修養

一忌 輕易言敗,沒有自信 沒有永不放棄精神的程式設計師,只是乙個有程式設計師名號的假程式設計師。乙個真正的程式設計師,知道在程式設計的過程中,可能會遇到不計其數的困難和問題,可能有極多的挫折和失敗,而成功只有一次。就為解決乙個問題,我們可能連續十幾甚至幾十小時的坐在計算機前不停的工作。乙個問題解決了...