1.**的編譯
clr(common language runtime),公共語言執行時,顧名思義,就是可以由多種語言使用的執行時,當我們用vs新建乙個原始碼檔案,寫好**,然後編譯的時候,實際會生成乙個託管模組,這個託管模組是乙個標準的windows pe32檔案,或者是乙個標準的windows pe32+檔案,該模組的組成部分為:
組成部分
說明pe32 或pe32+頭
標準windows pe檔案頭;如果這個頭使用pe32格式,檔案能在windows的32位或者64位版本上執行,如果這個頭使用的pe32+格式,檔案只能在windows 64位版本上執行
clr頭
包含使這個模組成為乙個託管模組的資訊
元資料每個託管模組都包含元資料表,主要有兩種型別的表:一種是描述源**中定義的型別和成員,另一種是藐視源**引用的型別和成員
il**
編譯器編譯源**生成的**,在執行時,clr會將il**編譯成本地cpu指令
預設情況下,編譯器會將託管模組轉換為程式集。
2.**的執行
託管程式集中同時包含元資料和il,il是一種與cpu無關的機器語言,當我們的程式首次執行時,會把要執行的il**編譯成本地cpu指令;這是clr的jit編譯器的職責。
舉個例子,如下**第一次執行:
demo
static在main方法執行前,clr會檢測main方法中所有引用的型別。這將導致clr分配乙個內部資料結構,它用於管理對所有引用的型別的訪問。在main中,有對console型別的引用,將分配乙個 內部資料結構,在這個資料結構中,console的每乙個方法都有乙個對應的記錄項,每乙個記錄項都容納了乙個可以找到方法實現的位址。對這個資料結構進行初始化時,clr將每個記錄項都設定成包含在clr內部的乙個未文件話的函式,我們稱之為jitcompiler。void main(string
args)
main方法第一次執行並呼叫console.writeline方法時,jitcompiler函式被呼叫時,它知道要呼叫的是哪個方法,然後就會找到該方法的il**,驗證並將其轉換為本地cpu指令,指令會被存到乙個動態分配的記憶體塊中,然後jitcompiler返回clr為型別建立的內部資料結構,找到與被呼叫方法對應的記錄項,修改對jitcompiler的引用為剛轉換的cpu指令記憶體塊的位址;最後jitcompiler會跳轉到記憶體塊中的**,執行完畢後就返回並繼續執行main中下面的**。
當main中第二次呼叫console.writeline相同的方法時,將會直接執行記憶體塊中的**,完全跳過jitcompiler。
所以,乙個方法只有在首次呼叫的時候才會造成一些效能損失,以後的呼叫都是以本地**的形式執行,無需驗證和編譯。
jit編譯器將本地cpu指令儲存到動態記憶體中,所以一旦程式終止編譯好的**也將被丟棄,再次執行程式或同時啟動兩個應用程式,jit編譯器將再次將il編譯成本地cpu指令。
3.il的驗證
將il編譯成本地cpu指令時,clr會執行乙個名為驗證的過程,這個過程會檢測高階il**,確保**所做的一切都是安全的,這也確保我們的應用程式的健壯性和安全性。
鄙人走在求知的道路中,寫部落格過程中如有不對或者理解錯誤之處希望大家不吝賜教,吾感激不盡。
CLR Via C 學習筆記之CLR的執行模型
1 公共語言執行時 common language runtime,clr 是乙個可由多種程式語言使用的 執行時 clr的核心功能 比如記憶體管理 程式集載入 安全性 異常處理和執行緒同步 可由面向clr的所有語言使用 2 c 源 檔案 c 編譯器 託管模組 中間語言il和元資料 無論選用哪個編譯器...
C 學習之程式
hello world test program 注釋,編譯器會忽略此處 include 預處理器編譯指令 include int main 函式頭 4 函式特性 有函式頭和函式體 接受乙個引數 返回乙個值 需要乙個原型 處理 號開頭的預處理命令,進行巨集替換,去掉 中的注釋。預編譯命令 g e h...
程式的編譯與連線
一 建立main.c 首先在linux環境中使用命令vim main.c寫乙個這樣的程式 include belongal define max 10 int g val1 11 int g val2 0 int g val3 static int g val5 11 static int g va...