你所不知道的C#: Compiler篇
基本Compiler原理
上圖即是一般編譯器的處理過程,編譯,組譯,連結,之後載入。
進階閱讀:
- 交大開放式課程: 作業系統設計與實作
- 工程師必讀: 程式設計師的自我修養
- 資工界的龍之書: 編譯系統設計
C# compiler原理
C#奠基於.NET Framework之上,.NET Framework所採用名叫JIT(Just In Time)的編譯技術,找出程式執行的熱點(Hot Spot),以進行即時編譯。
上圖即是C#編譯的過程,值得注意的是C# Compiler並沒有直接將程式碼編譯成Binary Code,而是先將程式碼編譯成MSIL(Microsoft Intermediated Language,微軟中間碼),在執行時期時利用.NET Framework內建的CLR(Common Language Runtime)執行JIT Compiler轉成Binary Code執行。
Hello World!!
以下是一段hello world的程式碼
using System;
namespace hello
{
class Program
{
public static void Main(string[] args)
{
System.Console.WriteLine("hello world");
}
}
}
利用csc.exe編譯完之後會產生一個exe檔。
使用ILSpy分析這個exe檔,會發現IL碼長這樣。
.namespace hello
{
.class private auto ansi beforefieldinit hello.Program
extends [mscorlib]System.Object
{
// Methods
.method public hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 13 (0xd)
.maxstack 8
.entrypoint
IL_0000: nop
IL_0001: ldstr "hello world"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret
} // end of method Program::Main
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x205e
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Program::.ctor
} // end of class hello.Program
}
值得注意的是第19行: call void [mscorlib]System.Console::WriteLine(string)。在IL階段並沒有把Console.WriteLine編進去,而是等到CLR載入時才編譯。