執行的前戲 編譯連線全過程理解

2021-06-25 18:51:14 字數 2211 閱讀 9507

一、 前言

高度封裝的事物(如各種ide)在提供便捷操作的同時也失去了許多美好的內部細節,往往讓讓使用者只知道how to use 而不知道how to achieve,因而在出現一些封裝內部的錯誤時就會讓使用者手足無措,因此了解其內部的大致執行過程將有助於處理一些整合環境不提示的錯誤。

二、基本概念

編譯:     編譯器對源**進行編譯,是將以文字形式存在的源**翻譯為機器語言形式的目標檔案的過程。

編譯單元:對於c++來說,每乙個cpp檔案就是乙個編譯單元。從之前的編譯過程的演示可以看出,各個編譯單元之間是互相不可知的。

目標檔案:由編譯所生成的檔案,以機器碼的形式包含了編譯單元裡所有的**和資料,以及一些其他的資訊。

三、 程式執行巨集觀流程

眾所周知,計算機和人類世界的關係就如同男人和女人的關係一樣,前者永遠無法基於乙個同等規則的世界中理解後者,因此人類要想和計算機交流就只能使用機器碼,但作為一名普通人類,顯然用一串串01相互交流是不太現實的,我們是好逸惡勞的生物,更喜歡使用人類自己的語言,這樣一來就需要一些中間媒介(編譯器)承擔乙個類似於adapter(介面卡)的角色。語言從低階到高階發展而來,有著自己不同的語法規則,因此不得不通過一層層的轉譯來實現和機器交流的過程(是不是很像網路協議棧這貨)。這個由高階語言**->低階語言**->機器碼->計算機識別執行的過程就是編譯執行的過程。

例如c語言的原始檔(**.c)->程式執行過程(**.exe)如下:

1、  原始檔(hello.c) -> 預處理器 –>  hello.i(文字檔案)

將include包含的標頭檔案進行解析,處理巨集定義和條件編譯命令,遮蔽無效的**段,最後生成新的源**hello.i

2、  hello.i  -> 編譯器 ->hello.s(彙編文字檔案)

經過編譯原理中的詞法和語法分析優化並生成彙編原始檔

3、  hello.s  ->  彙編器 -> hello.o(目標二進位制檔案)

生成機器碼並且包含編譯後生成的一些輔助表(後文會提及),封裝成目標檔案hello.o

4、  hello.o -> 聯結器 -> hello.exe

連線將要用到的庫檔案(.lib)和使用者自定義的標頭檔案中的內容(可能存在通過extern關鍵字相互共用的變數和函式),將其內容進行補充(函式和具體變數內容),最終               生成可執行檔案由機器執行。

四、 程式執行微觀過程

這裡主要摘取三中例子作為詳細分析。

三.1~三.3(嘿嘿,像不像物件例項呼叫內部成員)階段

object目標檔案中有如下三個表:

提供共享資料資訊的表:    

1、 未解析符號表

(unresolved symbol table):此表記錄當前編譯單元未被定義的變數,有可能來自系統庫或者使用者其他用extern標識的資料(符號+位址)。

2、 匯出符號表

3、位址重定位表

(address redirect table):此表提供本編譯單元對自身位址                  的記錄,用於找到真正的實體地址(直接加上偏移位址)。

三.4階段:

此階段在實際編譯執行過程中其實比較複雜(資料、**都分為不同區域),這裡只重點點明一下原理:

首先鏈結器找到每個object目標檔案的位置,通過位址重定向表(art表)對每個位址重定位,然後依次遍歷其ust表,從而知道了具體缺少哪些資料,然後從所有的est表中通過符號找到資料存放的位址並在相應位置處填上找到的具體位址,再做一些其他工作,最後生成乙個可執行檔案exe。

這樣可能更能便於各位geek們看懂:

for(every element i of ust)

if (lack_datum(ust[i].symbol))

}

五、總結事物都是一步步由簡單到複雜逐步發展起來的,看似輕鬆的編譯,其實也曾經歷了這麼多複雜的過程,向計算機的鼻祖和先驅們表示無限的敬意。

推薦,講得很詳細)

kinfu 編譯全過程

參考了很多網上編譯kinfu的教程,由於我同時裝了vs2012和vs2010,編譯的時候會出現the c compiler c program files microsoft visual studio 10.0 vc bin cl.exe is not able to compile a test...

編譯openwrt全過程

編譯openwrt全過程 本文 本教程的編譯環境 win7 專業版 vmwareworkstation6.5虛擬機器 ylmf os 3.0 編譯的過程中要保持電腦聯網 搭建編譯環境 應用程式 附件 終端 sudo apt get update 更新 安裝編譯需要的元件 sudo apt get i...

C語言編譯全過程

c語言編譯全過程 編譯的概念 編譯程式讀取源程式 字元流 對之進行詞法和語法的分析,將高階語言指令轉換為功能等效的彙編 再由匯程式設計序轉換為機器語言,並且按照作業系統對可執行檔案格式的要求鏈結生成可執行程式。編譯的完整過程 c源程式 預編譯處理 c 編譯 優化程式 s asm 匯程式設計序 obj...