CLR via C CLR執行模型

2021-09-08 17:37:09 字數 3632 閱讀 3817

事實上,可將編譯器視為語法檢查器和「正確**」分析器,它們檢查**,確定你所寫的一起都有意義,並輸出對你的意圖進行描述的**,編譯器的結果都是託管模組(標準的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的元...