NET框架程序設計讀書筆記(三)--執行程序集代碼
2024-07-21 02:17:13
供稿:網友
1.4執行程序集代碼
托管模塊中包含著元數據和il代碼。il是由微軟在咨詢了一些商業和學術上的語言編譯器作者之后開發的一種獨立于cpu的機器語言。il要比大多數cpu機器語言高級得多,它可以理解對象類型,并且擁有很多高級的指令,這些指令可以創建和初始化對象,調用對像上的虛方法以直接操作數組元素。它甚至還有拋出和捕獲異常的指令。我們可以把il視 作一種面向對像的機器語言。
通常情況上,開發人員會使用一門高級語言,比如:c#或visual basic)。這些語言的編譯器産的將是il代碼。當然,我們也可以直接以匯編語言的方法寫il程序。微軟也提供了一個il匯編器:ilasm.exe,另外還有一個反匯編器:ilddsm.exe 。
c# 或者visual basic 等高級語言提供的都只是clr全部功能的一個子集。 il匯編語言允許開發人員獲取clr所有的功能。
總結il的特點如下:
1、面向對像特性,與其他匯編不同。
2、il可以獲取clr所有的功能
3、il并不束縛于任何特定的cpu平臺,也就是說他也可以夸平臺。
.net程序執行過程如下:
1 一個方法執行之前,clr首先檢測main中代碼引用的所有類型,clr會分配一個內部的數據結構,該數據結構用于管理對所引用類型的訪問。
2、當該數據結構被初始化時,clr將把每一個條目設置 為clr內部的一個沒有正式記錄的函數,我們暫且稱該函數為 jitcompiler。
3、當main方法第一次調用引用的類型的方法成員時,jitcompiler函數將被調用,該函數負責將一個方法的il代碼編譯成本地cpu指令。
1、 jitcompiler將前面第2步的數據結構中的要調用的真實方法的地址替換成包含剛剛編譯好的cpu指令的內存塊地址。
2、 jitcompiler跳轉到該內存塊中的代碼上,開始執行。
注意:一個類型的所有方法只會編譯一次,當這個類型的方法又被調用時,將會使用之前已經編譯過的代碼,這樣只有在首次調用時,才會產生性能損失。
也就是說托管代碼跟非托管代碼相比,性能上的損失是非常小的,近乎微不足道。
托管代碼在性能上的優點:
1、 在新型的如奔4cpu上,jit編譯器能產生利用新型cpu提供的特殊指令的本地代碼。而非托管應用程序通常被編譯為向具有最小通用功能集合的cpu平臺,一般會避免使用新型cpu提供的特殊指令。而這些特殊指令往往會在較新的cpu上為應用程序帶來很高的性能提升中。
2、 jit編譯器能檢測到正在運行的機器上某些總是返回錯誤的布爾測試。例如:
if(numberofcpus>1)
{
}
如果宿主機器只有一個cpu,那么對于該段代碼,jit編譯器將不會產生任何cpu指令。針對宿主機器的本地代碼鶁會得到更好的調整:代碼量將變得更小,執行速度也會更快。
當然,我們可以利用ngen.exe工具,將il代碼轉化為本地代碼,并生成一個文件,這樣執行程序時,clr將自動檢查是否有個預編譯的版本存在,如果存在,clr將加載預編譯的代碼,不需要額外的運行時編譯。
1.4.1 il與代碼驗證
1、 il是一種基于堆棧的語言
2、 il沒有提供操作寄 存器的指令,開發人員可以很容易地產生il代碼。
3、 il需要的指令也比較少。
4、 il指令是無類型的。
5、 il對cpu實現了抽象。
il的最大優點是:提高了應用程序的健壯性,當il代碼被編譯為本地cpu指令時,clr將執行一個稱作驗證的過程。
驗證過程檢查高級il代碼,確保它做的每件事情都是“安全”的。以下是檢驗的一些條目:
1、 不能從未初始化的內存中讀取數據。
2、 每個方法都必須傳入正確的參數個數,且各個參數的類型要正確匹配。
3、 每個方法的返回值都必須被正確地使用。
4、 每個方法都必須有一個返回語句
。。。。
如果驗證不通過,將有一個system.security.verificationexception異常被拋出,阻止方法繼續執行。
驗證的優點:
通過驗證的代碼,我們可以確保它們不會訪問它們不應該訪問的的內存,因此也就不會干擾另一個應用程序的代碼。這意味著我們可以在一個單獨的windows虛擬地址空間內運行多個托管應用程序。