事實上,可將編譯器視為語法檢查器和「正確**」分析器,它們檢查**,確定你所寫的一起都有意義,並輸出對你的意圖進行描述的**,編譯器的結果都是託管模組(標準的32位microsoft windows可移植執行體(pe32)檔案或者標準的64位windows可移植執行體(pe32+)檔案)
《託管模組的各個部分》
組成部分
說明pe32或pe32+頭
標準window pe檔案頭,類似於「公共物件檔案格式」頭。如果這個頭使用pe32格式,檔案能在windows的32或64位版本上執行,如果這個頭使用pe32+格式,檔案只能在windows的64位版本上執行。這個頭還標識了檔案型別,包括gui,cui,或者dll,幷包含乙個時間標記來支出檔案的生成時間。對於只包含il**的模組,pe32+頭的大多數資訊會被忽視。如果只包含本機(native)cpu的**的模組,這個頭包含cpu**有關的資訊
clr頭
包含使這個模組成為託管模組的資訊(可由clr和一些實用程式解釋)。頭中包含要求的clr版本,一些標誌(flag),託管模組入口方法(main方法)的methoddef元資料token已經模組的元資料,資源,強名稱,一些標誌及其他不太重要的資料項的位置大小
元資料每個託管模組都包含元資料表。主要有兩種表:一種表描述源**中定義的型別和成員,另一種描述源**引用的型別和成員
il(中間語言)**
編譯器編譯源**時生成的**。在執行時,clr將il編譯成本機cpu指令
由於編譯器同時生成元資料和**,吧他們繫結在一起,並嵌入最終生成的託管模組,所以元資料和它描述的il**永遠不會失去同步
元資料有多種用途,下面列舉部分
程式集是抽象概念,是乙個或多個模組/資源的邏輯性分組,也是重用,安全性以及版本控制的最小單元。利用程式集,一組檔案可作為乙個單獨的實體對待。可以在不同的地方部署檔案,同時仍然將所有檔案作為乙個整體對待
《將託管模組合併成程式集》
要知道是否已安裝.net framework,只需檢查c:\windows\system32目錄中的mscoree.dll,存在則表明已安裝c#編譯器提供了乙個/platform命令列開關選項,這個選項允許指定最終生成的程式集在某個平台允許,如果不指定具體平台的話。預設選項就是anycpu
visual studio使用者要想設定目標平台,可以開啟專案的屬性頁,從「生成」選項卡的「目標平台」列表中選擇乙個選項
/platform開關
生成的託管模組
x86 windows
x64 windows
arm windows rt
anycpu(預設)
pe32/任意cpu架構
作為32位應用程式執行
作為64位應用程式執行
作為32位應用程式執行
anycpu32bitpreferred
pe32/任意cpu架構
作為32位應用程式執行
作為wow64應用程式執行
作為32位應用程式執行
x86pe32/x86
作為32位應用程式執行
作為wow64應用程式執行
不執行x64
pe32+/x64
不執行作為64為應用程式執行
不執行arm
pe32/arm
不執行不執行
作為32位應用程式執行
windows檢查exe檔案頭,決定是建立32位還是64位程序後,會在程序位址空間載入mscoree.dll的x86,x64或arm版本
高階語言通常只公開clr全部功能的乙個子集,il組合語言允許開發人員訪問clr的全部功能
《方法的首次呼叫》
在windows不同版本中執行將會得到不同指令(x86,x64,arm)《方法的第二次呼叫》
由於已對writeline的**進行了驗證和編譯,所以會直接執行**塊中的**,完全跳過jitcompiler函式,方法僅在首次呼叫時才會有一些效能損失clr的jit編譯器會對本機**進行優化,兩個c#編譯器開關會影響**優化
編譯器開關設定
c# il**質量
jit本機**質量
/optimize-/debug-(預設)
未優化有優化
/optimize-/debug(+/full/pdbonly)
未優化未優化
/optimize+/debug(-/+/full/pdbonly)
有優化有優化
使用/optimize-,在c#編譯器生成的未優化il**中,將包含許多nop(no-operation,空操作)指令,還包含許多跳轉到下一行**的分支指令,visual studio利用這些指令在除錯期間提供「編輯並繼續(edit-and-continue)」功能
託管**相較於非託管**的優勢
il基於棧。這意味者它的所有指令都要將運算元壓入(push)乙個執行棧,並從棧彈出(pop)結果。將il編譯成本機cpu指令時,clr執行乙個名為驗證(verification)的過程。這個過程會檢查高階il**,確定**所做的一切都是安全的。託管模組的元資料報含驗證過程要用到的所有方法及型別資訊。
microsoft c#編譯器也允許開發人員寫不安全的(unsafe)**。不安全的**允許直接操作記憶體位址,並可操作這些位址處的位元組。c#編譯器要求包含不安全**的所有方法都用unsafe關鍵字標記,除此之外,c#編譯器要求使用/unsafe編譯器開關來編譯源**。microsoft提供乙個名為peverify.exe的實用程式,它檢查乙個程式的所有方法,並報告其中含有不安全**的方法。
使用.net framework提供的ngen.exe工具,可以在應用程式安裝到使用者的計算機上時,將il**編譯成本機**。
ngen.exe編譯的優缺點優點
缺點.net framework包含framework類庫(framework class library,fcl)是組dll程式集的統稱,其中包含數千個型別定義,每個型別都公開一些功能。
部分應用程式
許多態別都允許自定義其行為,你只需從所需的fcl型別派生出自己的型別再進行自定義即可。
通用型別系統(common type system,cts),cts規範規定,乙個型別可以包含零個或多個成員。
cts還指定可見性規則和型別成員的訪問規則
cts規定所有型別最終必須從預定義的system.object型別繼承。system.object型別允許
microsoft定義了「公共語言規範」(comman language specification,cls),他詳細定義了乙個最小功能集。任何編譯器只有支援這個功能集,生成的型別才能相容由其他符合cls,面向clr的語言生成的元件。
clr支援三種互操作情形
c執行模型
段 1 編譯器把c語言 編輯成二進位制的指令 2 程式執行的時候把二進位制 載入到 段 3 段唯讀,不可改寫,這樣為了安全 4 cpu有乙個指令指標,指向當前執行的指令 5 cpu執行完一條指令後,在移動指令指標到下乙個位置 6 指令條件跳轉 7 指令迴圈跳轉 8 函式呼叫跳轉,函式返回跳轉,引數傳...
CLR執行模型
clr common language runtime 公共語言執行時,是乙個可由多種程式語言使用的 執行時 在執行時,clr根本不關心開發人員用的是哪一種語言來變寫 它只關注語言是否是面向clr 面向執行時 的.記憶體管理 程式集載入 安全性 異常處理和執行緒同步。3 如圖 無論是用的是哪一種編譯...
CLR執行模型
然後,將若干個託管模組合併成assembly.載入clr 在 system32 下有mscoreee.dll 說明已經安裝.首次執行一方法 在執行 main 之前,clr 建立乙個內部 ds來儲存 code 所引用的 type.呼叫方法時 jit complier將il 編譯為本地指令 在 am的元...