2021年11月27日準備發在基地微信公衆号上的推文。
綜合了多篇大佬的部落格,以及自己已經知道的知識,對一些疑惑進行了現階段我認為還算滿意的解答。
不過又産生了很多疑問:
記憶體和磁盤的關系
CPU是如何運作機器指令的(雖然大概想過去會是數字邏輯上的電路的組合)
......
========================================================================================================================================
我寫的上一篇推文是:Vscode裡的多檔案編譯,本來這一篇計劃是多語言混編,可是還沒玩太明白,就來補充講一講程式的運作過程,對上一篇也是一種補充。
當我們要讓一個程式運作起來,如下面這段代碼:
需要以下過程:
這一過程主要是處理源代碼檔案中:
以”#”開始的預編譯指令
如”#include”、”#define”等
将include的檔案插入進來,将所有define的宏定義展開。
删除注釋
添加行号和檔案名辨別。
以便編譯時編譯器産生調試用的行号資訊及用于編譯時産生編譯錯誤或警告時能夠顯示行号
編譯程式(Compiler)把預處理完的檔案進行一系列詞法分析、文法分析、語義分析及優化後生産相應的彙編代碼檔案。
當然,預處理和編譯可以合二為一,直接一步到位:
這裡提一下這個gcc,這隻是背景編譯程式(compiler)的控制台,會根據不同參數去調用不同的預處理、編譯程式,來處理不同的語言。
.o檔案就是“目标檔案”(Object File),将彙編語句轉換為機器語言,機器語言是CPU可以執行的指令。
在上面的過程中,原本的一個檔案會生成若幹個目标子產品,這些子產品是割裂的。
由連結程式(Linker)将這些目标子產品(程式段),以及它們所需要的庫函數連結在一起,形成一個完整的裝入子產品(Load Module);這是完整的執行指令的可執行檔案exe(此時已經是二進制檔案)。
連結分為靜态連結和動态連結。不展開了。
DLL檔案就是Dynamic Link Library檔案.
可執行檔案隻有裝載到記憶體以後才能被CPU執行。
裝入過程就是由裝入程式(Loader)将裝入子產品裝入實體記憶體。實體記憶體就是真實存在的記憶體條。
實體記憶體是由若幹個存儲單元組成的,每個存儲單元有一個編号,這種編号可唯一辨別一個存儲單元,稱為記憶體位址(或實體位址)。 可以簡單了解成類數組的一個結構。
這個過程進行了位址重定位,主要是将邏輯位址轉換成實體記憶體的絕對位址(相當于拿考号找座位)。這個過程隻有在程式将要被運作的時候才會發生。

執行不是一個嚴格的概念,隻是我用來描述裝入到輸出“Hello World”這個過程的一個名詞。
當計算機要運作該程式時,二進制檔案中相關的指令會發送給CPU,經過CPU的操作,顯示到了顯示器上。
補充GCC的工具鍊
程式從按下“編譯”到裝入記憶體需要哪些過程?
GCC工具鍊有哪些?