參考了jianqiang bao的筆記:
1.1 將源**編譯成託管模組
1. 生成什麼型別的應用程式或者組建(檔案);
(1)clr(common language runtime): 公共語言執行時;可由多種語言使用的執行時;---就是乙個執行時環境
什麼是clr...參考:
(在clr監視下執行的程式屬於"託管的"**,不在clr之下執行,直接在裸機上執行的應用或元件屬於"非託管的"**)
(2)clr的核心功能可由面向clr的所有語言使用.例如: 異常報告,建立執行緒...
(3)clr不關心使用的語言;
(4) 編譯器: 可將編譯器視為語法檢查器...
使用編譯器生成的都是乙個託管模組,--是乙個標準的32/64位可移植執行檔案,他們都需要clr才能執行
託管模組的組成部分:
@1 pe32/pe32+頭: 標準windows pe頭;
@2 clr頭: 包涵使這個模組成為乙個託管模組的資訊;
@3 元資料: 每個託管模組都包含元資料表; (什麼是元資料?:
元資料--簡單的說就是一組資料表,一些表描述了模組中定義的內容,一些表描述了託管模組引用的內容.元資料是一些老技術的超集.
元資料總是與il檔案關聯,事實上,元資料總是嵌入和**相同的exe/dll中
@4 il(中間語言**)**: 即編譯器編譯源**生成的**,在執行時,clr將il編譯成本地cpu指令; il**有時稱為 託管**,因為clr要管理它的執行
(5) 元資料的作用:
@1 消除對本地c/c++頭和庫檔案的需求,編譯器可以直接從託管模組中讀取元資料;
@2 智慧型提示...;
@3 確保只執行"型別安全"的操作;
@4 正反序列化;
@5 允許垃圾**器跟蹤物件的生存期;....
1.2 將託管模組合併成程式集
clr實際上是和程式集一起工作的,在clr世界裡,程式集相當於乙個"元件";
1. 程式集(assembly): @1 是乙個或者多個模組/資源檔案的分組;@2 是重用,安全性以及版本控制的最小單元;
2. 一些託管堆和資源檔案交由乙個工具(ex:c#編譯器)生成單獨乙個pe32(+)檔案來表示檔案的邏輯性分組;這個pe32(+)檔案包含乙個名為"清單"的
資料塊.清單表述程式集中的檔案集..
3. 預設情況下: 編譯器會把生成的託管模組轉換為程式集;c#編譯器生成含有清單的乙個託管模組,清單指出程式集只由乙個檔案構成;
1.3 載入公共語言執行時
1.clrver命令,檢視機器上所有的clr版本;
2.csc的/plattform開關,決定生成什麼樣子的程式集: anycpu,x86,x64,itanium;
1.4 執行程式集的**
高階語言(c#)只是clr的乙個子集,il則允許訪問clr的所有功能;
1. 託管程式集同時包含元資料和il(il是與cpu無關的語言),可將il視為一種物件導向的機器語言;
2. 為了執行乙個方法,首先必須把它的il轉換成本地cpu指令.-->這是clr的jit(just-in-time,"即時")編譯器的職責;
3. 乙個方法首次呼叫時發生的事情:
@1 在main()方法執行之前,由於main()引用了乙個console型別,clr會分配乙個內部結構,對這個結構進行初始化時,clr將每個記錄項都設定成指向包含
在clr內部的jitcompiler函式;
main()方法執行之前:clr會檢測出main()的**引用的所有型別,這導致clr分配乙個內部資料結構用於管理對所引用型別的訪問;
每個記錄項:在這個內部資料結構中,console型別定義的每個方法都有乙個對應的記錄項,每個記錄項都容納了乙個位址,根據此位址即可找到方法的實現;
@2 main()方法首次呼叫writeline時,jitcompiler函式會被呼叫.jitcompiler函式負責把乙個方法的il編譯成本地cpu指令.jitcompiler被呼叫時,它知道要
呼叫哪個方法以及具體是什麼型別定義了該方法
@3 jitcompiler會在定義該型別的程式集中查詢到被呼叫的方法的il;
@4 jitcompiler驗證il**,並將il**編譯成本地cpu指令.(本地cpu指令被儲存到乙個動態分配的記憶體塊中)
@5 jipcompiler返回clr為型別建立的內部資料結構,找到與被呼叫的方法對應的那一條記錄,修改最初對jitcompiler的引用,讓它指向記憶體塊的位址 ,
@6 jitcompiler跳轉到記憶體塊中的**.這些**正是writeline方法的實現.這些**執行完畢之後,會再次返回main中.
當第二次呼叫 writeline時,由於已經對writeline進行了驗證和編譯,所以會直接執行記憶體塊中的**,完全跳過jitcompiler函式,writeline執行完後再次返回
main方法;
4. 乙個方法只有在首次呼叫時才會造成一些效能損失
5. 有兩個開關會影響**的優化: /optimize和/debug. 預設時: /optimize-/debug- ,/optimize-在c#編譯時生成未優化的**,將包含許多nop指令,還有
許多分支指令,這些東東就讓我可以除錯**時可以設定斷點,...單步除錯...
6. **的編譯時分兩個階段編譯的: @1編譯器將源**生成il; @2clr中的jit再將il生成本地cpu指令...
7. 託管應用程式的效能實際上超過了非託管應用程式,...n多理由...
1.4.1 il和驗證
1. il是基於棧的,il也沒有提供操作操作暫存器的指令;
2. il的最大優勢: 應用程式的健壯性和安全性...將il編譯成本地cpu指令時:clr會執行乙個驗證的過程這個過程會檢查高階il是否安全;
3. 在windows中每個程序都有乙個虛擬位址空間,將每個程序放到獨立的位址空間中,可獲得健壯性和安全性.乙個程序無法干擾另乙個程序;
在windows中程序需要大量作業系統資源,程序數量太多會損害效能並制約可用資源;
@1 通過驗證託管**可確保**訪問正確的記憶體 @2 在乙個程序中執行多個應用程式
1.4.2 不安全的**
1. c#編譯器預設生成的**時安全的(safe)**.但是編譯器也允許寫不安全(unsafe)的**--不安全的**允許直接操作記憶體位址,並操作這些位址處的位元組.
通常只在與非託管的**進行互操作時使用,或者提公升對效率要求極高的演算法時用;
2. 重大風險: @1 破壞資料結構,危害安全; @2 甚至造成新的安全漏洞;
3. 要求所有的不安全代c碼都要使用unsafe關鍵字jit編譯器編譯時: 會檢查@1 許可權;@2 標誌是否設定;
1.6 framework類庫
1. .net framework中包涵了framework類庫(framework class library fcl). fcl就是一組dll檔案的統稱;
1.7 通用型別系統
1. clr完全是按照型別展開的.通過型別,不同的程式語言之間可以溝通.型別是clr的根本,因此微軟制定了這個正式規範: 通用型別系統--cts
common type system,描述了型別的定義和行為;
2. cts的規則:
@1 乙個型別可以包含0個或者多個成員;
@2 指定了型別的可視性規則和成員的訪問規則;
@3 為型別繼承,虛方法,物件生存期等定義了相應的規則;
@4 所有型別都是從預定義的system.object繼承.
1.8 公共語言規範
1. 公共語言規範 cls(common language specification)詳細定義了所有語言都必須支援的乙個最小功能集,
2. 在clr中: 乙個型別的每個成員要麼是乙個字段要麼是乙個方法...源**最後都會被編譯為字段或者方法.
1.9 與非託管**的互操作性
1. 託管**能呼叫dll中的非託管**;
2. 託管**可以使用現有的com元件;
3. 非託管**可以使用託管型別;
---本人菜鳥一枚....呵呵...有點抄書的感覺,第一次寫讀書筆記.差不多兩個星期才看完這一章,主要是每天都沒怎麼看,下班回來就上網幹別的了...( ⊙ o ⊙ )! 木有恆心!!!該打...嘿嘿...繼續加油,給自己做的筆記..歡迎拍磚.
第一章 CLR執行模型
發現看過好幾遍還是會忘記,因水平有限理解的不是很到位。歡迎各位大神及時指正。clr執行模型 1.1編譯器將源 編譯成託管模組 託管模組 是標準的windows可移植執行體檔案 pe32 32位機器 或者pe32 64位機器 它們需要clr 才能執行 1.2 編譯器將託管模組合併成程式集 託管模組有四...
第一章 CLR的執行模型
編譯器將源 編譯為託管模組.託管木塊包含 pe32或pe32 頭 clr頭 元資料il 中間語言 pe32頭的檔案可在32或64位的電腦上執行,pe32 的只能在64上執行.window64位版本提供了乙個wow64的技術,允許32位的程式執行.clrver.exe能夠列出一台電腦上安裝的所有的cl...
第一章 CLR的執行模型
概念篇 可由多種程式語言使用的執行環境,提供記憶體管理 程式集載入 安全性 異常處理和執行緒同步等支援。規範化的型別定義和管理,比如 字段 方法等,又比如繼承等特性。針對clr cts定義的最基本的組建。標準的32位mircorsofte windows 可移植執行提 pe32 檔案 或者是標準的6...