首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

認識元數據與 IL(中):元數據表結構、堆與 IL 指令集詳解

     編輯:關於.NET

承接[上集](第二十四回),本文系統梳理 CLR 元數據的 44 張標準表、6 大堆結構,以及 IL 指令集特性與 Metadata Token 參考機制。

元數據表:44 張表的完整分類

每個模組包含 44 張元數據表(ECMA-335 標準),主要分類:

類別代表表說明
定義表TypeDef (0x02)模組內定義的所有類型
MethodDef (0x06)方法定義(含 IL 代碼 RVA)
FieldDef (0x04)欄位定義
PropertyDef (0x17)屬性定義
ModuleDef (0x00)模組本身資訊
引用表TypeRef (0x01)引用外部類型
MemberRef (0x0A)引用外部成員(方法/欄位/屬性)
AssemblyRef (0x23)引用外部組件
ModuleRef (0x1A)引用外部模組
指標表MethodPtr (0x05)方法定義中間查找表
FieldPtr (0x03)欄位定義中間查找表
ParamPtr (0x07)參數定義中間查找表
其他關鍵表InterfaceImpl (0x09)類型實作介面對應
CustomAttribute (0x0C)屬性實例資料
GenericParam (0x2A)泛型類型/方法參數
MethodSpec (0x2B)泛型方法實例化
Assembly (0x20)組件清單定義

表之間透過 RID (Record ID) 形成關聯圖,類似關聯式資料庫外鍵關係。例如 TypeDef 記錄擁有 FieldList、MethodList 指向對應定義表起始 RID。

六大堆:字串、Blob、US、GUID、~、-

堆內容備註
#StringASCII 字串:類型/方法/欄位名稱不含程式碼字面常數
#USUnicode 字串:程式碼字面常數 (ldstr)string s = "hello" 中的 "hello"
#Blob二進位物件:簽章、常數值、自訂屬性資料壓縮格式
#GUID128-bit GUID 值供表引用
#~壓縮後的所有元數據表主要儲存區
#-未壓縮的 #~Edit-and-Continue 用

關鍵區別:string hello = "Hello" 中,變數名 hello 存 #String,字面值 "Hello" 存 #US。

IL 指令集核心特性

  • 面向物件機器語言:擁有類別、物件、繼承、多型指令
  • CPU 無關:JIT 負責轉換為原生碼
  • 堆疊基礎執行模型:參數、區域變數、返回值在評估堆疊操作
  • Metadata Token 參考元數據:4 位元組 Token 編碼表索引 + RID

IL 代碼範例與 Token 解讀

.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 2
    .locals init ([0] int32 id,
                  [1] class .../One,
                  [2] class .../Two)
    IL_0000: nop
    IL_0001: ldc.i4.1
    IL_0002: stloc.0
    IL_0003: newobj instance void .../One::.ctor() /* 06000007 */
    IL_0008: stloc.1
    IL_0009: ldloc.1
    IL_000a: ldloc.0
    IL_000b: callvirt instance void .../One::set_ID(int32) /* 06000006 */
    IL_0011: newobj instance void .../Two::.ctor() /* 06000002 */
    IL_0016: stloc.2
    IL_0017: ldloc.2
    IL_0018: callvirt instance string .../Two::SayHello() /* 06000001 */
    IL_001d: call void [mscorlib]System.Console::WriteLine(string) /* 0A000011 */
    IL_0022: nop
    IL_0023: ret
}

Token 解碼:06000007 → MethodDef 表 (0x06) 第 7 筆記錄。

反射存取元數據 Token

Console.WriteLine(typeof(One).MetadataToken); // 輸出 0x02000004 (TypeDef 表第 4 筆)

小結

元數據表定義靜態結構,堆儲存變長資料,IL 透過 Token 串聯兩者。下集將實戰展示 JIT 編譯階段這套機制如何驅動程式執行。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved