// HelloWorld.cs
using System;
class HelloWorld {
public static void Main() {
Console.WriteLine("Hello World !");
}
}
編譯:csc HelloWorld.cs → HelloWorld.exe
執行:HelloWorld → 輸出 Hello World !
看似平凡,實則串聯:Roslyn 編譯器 → PE/COFF 格式 → IL + 中繼資料 → CLR 載入器 → JIT 編譯 → 原生執行 → GC 管理。本文逐層剖析。
using System;:命名空間導入指示詞,簡化 System.Console 為 Console,不影響輸出 IL。class HelloWorld:參考型別,隱含繼承 System.Object。public static void Main():程式進入點,CLR 尋找特徵:static、void/int 回傳、無參數或 string[]、大寫 Main(區分大小寫)。Console.WriteLine:呼叫 BCL 靜態方法,最終透過 TextWriter 輸出至標準輸出流。HelloWorld.exe 不是 傳統原生機器碼 EXE,而是 PE (Portable Executable) 檔,包含:
IMAGE_FILE_MACHINE_I386/AMD64)、區段數、時間戳記。CorFlags:ILOnly、32BitRequired、32BitPreferred、Signed)MethodDef:Main).text:IL 程式碼.rsrc:資源.reloc:重新定位表中繼資料是編譯器產生的關聯式資料表,儲存:
[Serializable]、[Obsolete]、[DllImport] 等)。作用:
① 類型安全驗證(JIT 驗證 IL)
② 反射(System.Reflection)
③ 序列化/還原序列化
④ 互操作(COM/WinRT/P/Invoke)
⑤ 工具支援(IntelliSense、偵錯、ILDasm、編輯後繼續)
使用 ildasm HelloWorld.exe /output:HelloWorld.il 反組譯:
.class private auto ansi beforefieldinit HelloWorld
extends [mscorlib]System.Object
{
.method public hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 8
IL_0000: ldstr "Hello World !"
IL_0005: call void [mscorlib]System.Console::WriteLine(string)
IL_000a: ret
}
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
}
}
| 指令 | 語意 |
|---|---|
.entrypoint | 標記 CLR 進入點(僅一個方法可標記) |
.maxstack 8 | 評估堆疊最大深度(JIT 配置暫存器/堆疊空間) |
ldstr | 推入字串常值參考(自動驻留) |
call | 呼叫方法(非虛擬、靜態、建構函式) |
ret | 從方法返回 |
ldarg.0 | 載入第 0 個引數(實例方法為 this) |
特徵:堆疊機器模型、強型別、物件導向指令(newobj、callvirt、ldfld、stfld、throw、leave)、異常處理區塊(.try/catch/finally/fault)。
AddressOfEntryPoint(實為 mscoree.dll!_CorExeMain 或 _CorDllMain)。AppDomain(.NET Framework)或 AssemblyLoadContext(.NET Core)。mscorlib / System.Private.CoreLib)。Finalize、卸載 AppDomain、釋放記憶體、歸還 OS。| 技術 | 原理 | 優勢 |
|---|---|---|
| Tiered Compilation | 首次呼叫快速編譯 (Tier 0) → 熱點方法重新優化編譯 (Tier 1) | 啟動快、峰值效能高 |
| ReadyToRun (R2R) | 建置時預先編譯部分/全部 IL → 原生碼嵌入 PE | 減少 JIT 延遲、啟動加速 |
| Native AOT | 發布時完整編譯為原生可執行檔,無 JIT、無 IL | 極小體積、瞬間啟動、無 IL 逆向風險 |
ildasm / ilasm:IL 反組譯/組譯。dotnet-ildasm:跨平台 .NET Core 版。dotnet dump collect / analyze:傾印/分析核心傾印(Linux/macOS/Windows)。PerfView / dotnet-trace / dotnet-counters:效能分析、GC 統計、事件追蹤。dnSpy / ILSpy:.NET Framework 組件反編譯器(含原始碼還原)。一行 Console.WriteLine,串聯了編譯器前端(語法分析、語意分析、IL 發射)、PE/COFF 容器格式、中繼資料關聯模型、CLR 載入器、JIT 編譯器、執行期服務(GC、執行緒、安全性、互操作)。深入理解這條工程鏈,不僅能解開「為什麼 EXE 能跑」的謎題,更能在效能調優、逆向工程、跨平台部署、安全性稽核等進階領域遊刃有餘。這正是 C# 與 .NET 平台「銳利」的根基所在。