中繼資料是儲存在 .NET Framework 可移植執行檔 (PE) 的一個區段中,而 Microsoft Intermediate Language (MSIL) 則是儲存在 PE 檔的另一個區段。檔案的中繼資料部分包含一系列表格和堆積 (Heap) 資料結構。MSIL 部分包含參考 PE 檔中繼資料部分的 MSIL 和中繼資料語彙基元 (Token)。當您使用工具,例如 MSIL 反組譯工具 (Ildasm.exe) 來檢視您程式碼的 MSIL,或執行階段偵錯工具 (Cordbg.exe) 來執行記憶體傾印的時候,您可能遇到中繼資料語彙基元。
中繼資料表和堆積
各個中繼資料表都儲存您程式項目的資訊。例如,某個中繼資料表描述您程式碼的類別,而另一個表格則描述欄位等等。如果您的程式碼中有十個類別,類別表格將會有十列,一列對應一個類別。中繼資料表會參考其他表格和堆積。例如,類別的中繼資料表會參考方法的表格。
中繼資料也將資訊儲存在四種堆積結構中:字串、BLOB (二進位大型物件)、使用者字串和 GUID。所有用於命名型別和成員的字串都儲存在字串堆積中。例如,方法表格不直接儲存特定方法的名稱,但指向儲存在字串堆積中的方法名稱。
中繼資料語彙基元
各個中繼資料表的每一列在 PE 檔的 MSIL 部分由中繼資料語彙基元來唯一辨識。中繼資料語彙基元在概念上類似指標,它保存 (Persist) 在 MSIL 中,並參考特定中繼資料表。
中繼資料語彙基元為四位元組數字。第一個位元組代表特定語彙基元所參考的中繼資料表 (方法、型別等等)。剩餘三個位元組指定中繼資料表中的列,對應正在描述的程式設計項目。如果您以 C# 定義方法,並編譯它為 PE 檔,下列中繼資料語彙基元可能存在於 PE 檔的 MSIL 部分:
0x06000004
第一個位元組 (0x06) 表示這是 MethodDef 語彙基元 (Token)。下面的三個位元組 (000004) 會告知 Common Language Runtime 到 MethodDef 表格的第四列尋找說明這個方法定義的資訊。
PE 檔內的中繼資料
當編譯 Common Language Runtime 的程式時,它被轉換至由三部分組成的 PE 檔。下表說明各部分的內容。
| PE 區段 | PE 區段的內容 |
|---|---|
PE 標頭 |
PE 檔主要區段的索引和進入點 (Entry Point) 的位址。 執行階段會使用這個資訊辨識檔案為 PE 檔,並決定當載入程式至記憶體時,於何處開始執行。 |
MSIL 指令 |
構成您程式碼的 Microsoft Intermediate Language 指令 (MSIL)。許多 MSIL 指令都有中繼資料語彙基元伴隨。 |
中繼資料 |
中繼資料表和堆積。執行階段會使用這個區段來記錄您程式碼中一切型別和成員的資訊。這個區段也包括自訂屬性和安全性資訊。 |