你所不知道的C#: Compiler篇

Author Avatar
高宇哲 2月 24, 2017

基本Compiler原理

Compiler-flow

上圖即是一般編譯器的處理過程,編譯,組譯,連結,之後載入。

編譯示意圖
編譯示意圖
連結示意圖
連結示意圖
載入示意圖
載入示意圖

進階閱讀:

  1. 交大開放式課程: 作業系統設計與實作
  2. 工程師必讀: 程式設計師的自我修養
  3. 資工界的龍之書: 編譯系統設計

C# compiler原理

C#奠基於.NET Framework之上,.NET Framework所採用名叫JIT(Just In Time)的編譯技術,找出程式執行的熱點(Hot Spot),以進行即時編譯。

CSharp-Compiler-Flow

上圖即是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載入時才編譯。