【Note】淺談編譯


BY《程序是怎樣跑起來的》

1.基本知識

(1)源代碼:用某種編程語言編寫的程序。
(2)源文件:保存源代碼的文件,是簡單的文本文件。
(3)CPU能直接解析並運行的不是源代碼而是本地代碼的程序,只能解釋已經轉換稱本地代碼的程序內容。用任何編程語言編寫的源代碼,最後都要翻譯成本地代碼。
(4)Windows中EXE文件的程序內容,使用的就是本地代碼。本地代碼的內容是人類無法理解的。

2.DUMP下EXE文件內容

dump:把文件的內容,每個字節用2位16進制數來表示的方法。每個數值都表示某一個命令或數據。
本地代碼的真面目是數值的羅列。

3.編譯器——負責轉換源代碼

(1)含義:把高級編程語言編寫的源代碼轉換成本地代碼的程序。
(2)過程:編譯器讀入代碼內容,把源代碼轉換成本地代碼。注意:讀入的代碼進行轉換非簡單的對應映射,讀入的源代碼需經過語法解析、句法解析、語義解析等,才能生成本地代碼。
(3)編譯器與編程語言的種類及CPU類型相關。
源代碼轉化成源代碼
(4)編譯器本身也是程序的一種,故也需要運行環境。
(關於運行環境,見上篇: link.)

存在交叉編譯器,它生成和運行環境中的CPU不同的CPU所使用的本地代碼。EG,奔騰系列CPU的WINDOWS這一運行環境下,可作成SH及MIPS等CPU用的WINDOWS CE程序,這是通過使用交叉編譯器實現的。
交叉編譯器

(5)確定編譯器的3個關鍵詞:
那種編程語言使用的編譯器;編譯器生成的本地代碼用於哪種CPU;編譯器在哪種環境下使用。

4.鏈接——本地文件到可執行(EXE)文件

鏈接:把多個目標文件結合,生成1個exe文件的處理就是鏈接,運行連接的程序就稱爲鏈接器(linkage editor 或連結器)。

目標文件(object file)中的object一詞,指的是編譯器生成結果的意思。而面向對象編程的對象指的是數據和處理的集合體。

5.DLL文件&導入庫

應用程序接口,API,Application Programming Interface。

如某main函數文件調用messageBox()內置函數,它並不是C語言的標準函數,而是WINDOWS提供的API一種。

windows中,API的目標文件不是存儲在庫文件中,而是存儲在名爲DLL(Dynamic Link Library)文件的特殊庫文件中。DLL文件是程序運行時動態結合的文件。

靜態鏈接庫:存儲目標文件的實體,並直接和EXE文件結合的庫文件形式。

6.EXE文件運行機制

EXE文件作爲單獨文件儲存在硬盤中。雙擊打開它,就會把其內容記載到內存上。
EXE文件中給變量及函數分配虛擬的內存地址,程序運行時,虛擬轉換成實際的內存地址。鏈接器會在EXE文件的開頭,追加轉換內存地址所需的必要信息,即再配置信息,是變量和函數的相對地址,表示相對於基點地址的偏移量。基點地址是在程序運行時被分配的。

7.棧&堆

EXE文件內容分爲再配置信息、變量組、函數組。
程序加載到內存後,還會額外生成兩個組,棧和堆。
(1)棧:存儲函數內部臨時使用的變量(局部變量),及函數調用時所用的參數的內存區域。
(2)堆:存儲程序運行時的任意數據及對象的內存區域。
運行中的程序

棧和堆的內存空間都是在程序運行時得到申請分配的。
棧:其中堆數據進行存儲和捨棄(清理處理)的代碼,是由編譯器自動生成的,不需程序員參與。使用棧的數據的內存空間,每當函數被調用時都會得到申請分配,並在函數處理完畢後自動釋放。
堆:需根據程序員編寫的程序,來明確進行申請分配或釋放。

8.問答

Q1:使用DLL文件的好處?
A1:DLL文件中的函數可被多個程序共用。因此,藉助該功能可節約內存和磁盤。對函數的內容進行修正時,還不需重新鏈接(靜態鏈接)使用這個函數的程序。

Q2:把多個目標文件收錄在一起的文件稱爲什麼?
A2:庫文件。鏈接器會從庫文件中抽取出必要的目標文件並將其結合到EXE文件中。此外,還存在一種程序運行時結合的DLL形式的庫文件。

Q3:僅包含WINDOWS的DLL文件中存儲的函數信息的文件稱爲什麼?
A3:導入庫。把導入庫信息結合到EXE文件中,則程序在運行時就可利用DLL內的函數。

Q4:程序運行時,用來動態申請分配的數據和對象的內存區域形式稱爲什麼?
A4:堆。堆的內存空間會根據程序的命令進行申請及釋放。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章