共用方式為


編譯 MSIL 為機器碼

在可以執行 Microsoft Intermediate Language (MSIL) 之前,必須以 .NET Framework Just-In-Time (JIT) 編譯器將其轉換為機器碼,此為 CPU 特定程式碼,可在與 JIT 編譯器相同的電腦架構中執行。由於 Common Language Runtime 會為每個支援的 CPU 架構提供 JIT 編譯器,因此開發人員可以撰寫可在不同架構的電腦上進行 JIT 編譯和執行的 MSIL 集。然而,如果您的 Managed 程式碼呼叫特定平台的原生 (Native) API 或特定平台的類別庫,便只能在特定的作業系統中執行。

JIT 編譯會考慮某些程式碼在執行期間可能從不會被呼叫的事實。它並非使用時間和記憶體將可攜式執行檔 (PE) 中所有的 MSIL 轉換為機器碼,而是在執行期間依需要轉換 MSIL 並儲存產生的機器碼,以供後續呼叫的存取。載入器於載入型別時會建立並附加 Stub 至型別中的每一個方法。當第一次呼叫方法時,Stub 會立即傳遞控制權給 JIT 編譯器,它會將那個方法的 MSIL 轉換成機器碼,並修改 Stub 以將執行導向至機器碼的位置。JIT 編譯方法的後續呼叫會直接使用先前產生的機器碼,縮短耗在 JIT 編譯和執行程式碼的時間。

Runtime 還提供另外一種編譯模式,稱為安裝階段程式碼產生。安裝階段程式碼產生模式正如一般 JIT 編譯器一樣,會將 MSIL 轉換成機器碼,但會一次轉換較大單位的程式碼,並儲存產生的機器碼,以供後續載入和執行組件 (Assembly) 時使用。使用安裝階段程式碼產生時,會將其他已安裝組件的已知情形納入考慮,而將正要安裝的整個組件轉換成機器碼。產生的檔案在載入和啟動時比它用標準 JIT 選項轉換為機器碼時更為快速。

在將 MSIL 編譯成機器碼的過程中,程式碼必須通過驗證程序,除非系統管理員建立的安全性原則允許程式碼略過驗證。驗證會檢查 MSIL 和中繼資料 (Metadata),以找出該程式碼是否為型別安全,這表示它僅存取獲得授權可存取的記憶體位置。型別安全有助於隔離出各物件,因此也就能夠免於無心或蓄意的毀損。它也提供保證,程式碼的安全性限制將會可靠地強制執行。

對 Runtime 而言,一個可以被確認為型別安全的程式碼會滿足下列條件:

  • 型別的參考與正被參考的型別完全相容。
  • 只有適當定義的作業在物件上被叫用 (Invoke)。
  • 識別 (Identity) 是它們所要求的。

在驗證處理期間,MSIL 程式碼會受檢查以確認程式碼只會使用有正確定義的型別來存取記憶體位置和呼叫方法。例如,對於一個會存取超出物件欄位記憶體範圍外位址的程式碼是不被允許的。此外,驗證會檢視程式碼,以判斷 MSIL 是否已經正確產生,因為不正確的 MSIL 可能會違反型別安全規則。驗證程序會讓妥善定義的型別安全程式碼集合通過驗證,它也只會讓型別安全的程式碼通過驗證。然而,由於驗證程序的限制,某些型別安全程式碼可能無法通過驗證,而某些語言由於設計之故,不會產生可確認的型別安全程式碼。如果安全性原則需要型別安全程式碼,而該程式碼沒有通過驗證,則在程式碼執行時會產生例外狀況 (Exception)。

請參閱

Managed 執行程序