要講到c#源碼的執(zhí)行過程 首先要提下程序集,因?yàn)閏lr并不是和托管摸塊打交道的,而是和程序集(dll,exe)
1、從哪里來
程序集是由一個(gè)或者多個(gè)托管模塊以及 資源文件等共同組成的,c#編譯器(csc.exe)再把源碼編程成il代碼和元數(shù)據(jù)的時(shí)候,會(huì)進(jìn)一步連同資源文件合并成程序集,
實(shí)際上就是個(gè)pe32文件,里面包含一個(gè)清單文件 和多個(gè)托管模塊和資源(如圖),另外程序集中還有一些自描述信息。
2、執(zhí)行過程
編譯器生成好程序集以后,如果是可執(zhí)行的程序集,會(huì)在main方法執(zhí)行之前,window會(huì)預(yù)先讀取程序集的頭文件(pe32),如果是x86則開一個(gè)32位的進(jìn)程,x64的就開一個(gè)64位的進(jìn)程
然后在進(jìn)程空間里面加載mscoree.dll的x86 或者x64版本或者arm版本,然后進(jìn)程的主線程會(huì)調(diào)用mscoree.dll的一個(gè)方法,初始化clr,而clr會(huì)加載程序集exe,再調(diào)用其入口方法main。
3.main方法內(nèi)部執(zhí)行
在main執(zhí)行之前,clr 會(huì)檢測出方法引用的所有類型,(console),然后在內(nèi)存中分配對應(yīng)數(shù)據(jù)類型的空間,這個(gè)地址里面包含著這個(gè)類型所有的方法聲名,每一項(xiàng)都對應(yīng)著clr里面的一個(gè)未編檔函數(shù)(jitcompiler)
首次運(yùn)行main方法的試試jitcompiler會(huì)被調(diào)用,在這個(gè)方法里面1,負(fù)責(zé)在方法的實(shí)現(xiàn)類型中(console)程序集元數(shù)據(jù)中查詢該方法的il方法 2,動(dòng)態(tài)分配內(nèi)存塊 3,把il編譯成本機(jī)cpu的指令,存儲(chǔ)到動(dòng)態(tài)分配的空間里面
4,修改這個(gè)條目的地址,使它指向動(dòng)態(tài)分配的地址 5.跳轉(zhuǎn)到內(nèi)存塊中的本機(jī)代碼執(zhí)行,這時(shí)候執(zhí)行的就是il代碼的cpu機(jī)器碼
5.在次執(zhí)行console.writeline的時(shí)候,就不會(huì)運(yùn)行jitcompiler,直接運(yùn)行機(jī)器碼
原文鏈接:https://www.cnblogs.com/wupo/p/9373564.html