亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

什么是NET中IL(圖文詳解)

發布時間:2021-10-11 23:30:05 來源:億速云 閱讀:169 作者:iii 欄目:開發技術

這篇文章主要介紹“什么是NET中IL(圖文詳解)”,在日常操作中,相信很多人在什么是NET中IL(圖文詳解)問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”什么是NET中IL(圖文詳解)”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

接觸NET也有1年左右的時間了,NET的內部實現對我產生了很大的吸引力。個人覺得:能對這些底部的實現進行了解和熟練的話,對以后自己寫代碼是有很大幫助的,好了,廢話不多說,請看下邊:

.NET CLR 和 Java VM 都是堆疊式虛擬機器(Stack-Based VM),也就是說,它們的指令集(Instruction Set)都是採用堆疊運算的方式:執行時的資料都是先放在堆疊中,再進行運算。JavaVM 有約 200 個指令(Instruction),每個指令都是 1 byte 的 opcode(操作碼),后面接不等數目的參數;.NET CLR 有超過 220個指令,但是有些指令使用相同的 opcode,所以 opcode 的數目比指令數略少。特別注意,.NET 的 opcode 長度並不固定,大部分的 opcode 長度是 1 byte,少部分是 2 byte。

下面是一個簡單的 C# 原始碼:                

復制代碼 代碼如下:


using System;
public class Test {
    public static void Main(String[] args) {
        int i=1;
        int j=2;
        int k=3;
        int answer = i+j+k;
        Console.WriteLine("i+j+k="+answer);
    }
}


將此原始碼編譯之后,可以得到一個 EXE的程序。我們可以通過 ILDASM.EXE(圖-0) 來反編譯 EXE 以觀察IL。我將 Main() 的 IL 反編譯條列如下,這裡共有十八道IL 指令,有的指令(例如 ldstr 與 box)后面需要接參數,有的指令(例如 ldc.i4.1 與與add)后面不需要接參數。什么是NET中IL(圖文詳解)
圖-0
ldc.i4.1
stloc.0
ldc.i4.2
stloc.1
ldc.i4.3
stloc.2
ldloc.0
ldloc.1
add
ldloc.2
add
stloc.3
ldstr      "i+j+k="
ldloc.3
box        [mscorlib]System.Int32
call       string [mscorlib]System.String::Concat(object, object)
call       void [mscorlib]System.Console::WriteLine(string)
ret

此程式執行時,關鍵的記憶體有三種,分別是:

1、Managed Heap:這是動態配置(Dynamic Allocation)的記憶體,由 Garbage Collector(GC)在執行時自動管理,整個Process 共用一個 Managed Heap。

2、Call Stack:這是由 .NET CLR 在執行時自動管理的記憶體,每個 Thread 都有自己專屬的 Call Stack。每呼叫一次 method,就會使得Call Stack 上多了一個 Record Frame;呼叫完畢之后,此 Record Frame 會被丟棄。一般來說,Record Frame 內記錄著 method 參數(Parameter)、返回位址(Return Address)、以及區域變數(Local Variable)。Java VM 和 .NET CLR 都是使用 0, 1, 2… 編號的方式來識別區別變數。

3、Evaluation Stack:這是由 .NET CLR 在執行時自動管理的記憶體,每個 Thread 都有自己專屬的 Evaluation Stack。前面所謂的堆疊式虛擬機器,指的就是這個堆疊。

后面有一連串的示意圖,用來解說在執行時此三種記憶體的變化。首先,在進入 Main() 之后,尚未執行任何指令之前,記憶體的狀況如圖1 所示:

什么是NET中IL(圖文詳解)

圖1                

接著要執行第一道指令 ldc.i4.1。此指令的意思是:在 Evaluation Stack 置入一個 4 byte 的常數,其值為 1。執行完此道指令之后,記憶體的變化如圖2 所示:

ldc.i4.1:表示加載一個值為1到堆棧中,該條指令的語法結構是:
ldc.typevalue:ldc指令加載一個指定類型的常量到stack.
ldc.i4.number:ldc指令更加有效.它傳輸一個整型值-1以及0到8之間的整數給計算堆棧

什么是NET中IL(圖文詳解)

圖2       

接著要執行第二道指令 stloc.0。此指令的意思是:從 Evaluation Stack 取出一個值,放到第 0 號變數(V0)中。這裡的第 0 號變數其實就是原始碼中的i。執行完此道指令之后,記憶體的變化如圖3 所示:

什么是NET中IL(圖文詳解)

圖3                

后面的第三道指令和第五道指令雷同於第一道指令,且第四道指令和第六道指令雷同於第二道指令。為了節省篇幅,我不在此一一贅述。提醒大家第 1 號變數(V1)其實就是原始碼中的 j,且第 2 號變數(V2)其實就是源碼中的 k。圖4~7 分別是執行完第三~六道指令之后,記憶體的變化圖:

什么是NET中IL(圖文詳解)

圖4                

什么是NET中IL(圖文詳解)

圖5

什么是NET中IL(圖文詳解)
圖6

什么是NET中IL(圖文詳解)
圖7

接著要執行第七道指令 ldloc.0 以及第八道指令 ldloc.1:分別將 V0(也就是 i)和 V1(也就是 j)的值放到 Evaluation Stack,這是相加前的準備動作。圖8 與圖9 分別是執行完第七、第八道指令之后,記憶體的變化圖:

什么是NET中IL(圖文詳解)

圖8

什么是NET中IL(圖文詳解)
圖9

接著要執行第九道指令 add。此指令的意思是:從 Evaluation Stack 取出兩個值(也就是 i 和 j),相加之后將結果放回 Evaluation Stack 中。執行完此道指令之后,記憶體的變化如圖10 所示:

什么是NET中IL(圖文詳解)
圖10

接著要執行第十道指令 ldloc.2。此指令的意思是:分別將 V2(也就是 k)的值放到 Evaluation Stack,這是相加前的準備動作。執行完此道指令之后,記憶體的變化如圖11 所示:

什么是NET中IL(圖文詳解)
圖11

接著要執行第十一道指令 add。從 Evaluation Stack 取出兩個值,相加之后將結果放回 Evaluation Stack 中,此為 i+j+k 的值。執行完此道指令之后,記憶體的變化如圖12 所示:

什么是NET中IL(圖文詳解)
圖12

接著要執行第十二道指令 stloc.3。從 Evaluation Stack 取出一個值,放到第 3 號變數(V3)中。這裡的第3號變數其實就是原始碼中的 answer。執行完此道指令之后,記憶體的變化如圖13 所示:

什么是NET中IL(圖文詳解)
圖13

接著要執行第十三道指令 ldstr "i+j+k="。此指令的意思是:將 "i+j+k=" 的 Reference 放進 Evaluation Stack。執行完此道指令之后,記憶體的變化如圖14 所示:

什么是NET中IL(圖文詳解)
圖14

接著要執行第十四道指令 ldloc.3。將 V3 的值放進 Evaluation Stack。執行完此道指令之后,記憶體的變化如圖15 所示:

什么是NET中IL(圖文詳解)
圖15

接著要執行第十五道指令 box [mscorlib]System.Int32,從此處可以看出,int到string實際是進行了裝箱操作的,所以會有性能損失,可以在以后的編碼中減少裝箱操作來提高性能。此指令的意思是:從 Evaluation Stack 中取出一個值,將此 Value Type 包裝(box)成為 Reference Type。執行完此道指令之后,記憶體的變化如圖16 所示:

什么是NET中IL(圖文詳解)
圖16

接著要執行第十六道指令 call string [mscorlib] System.String::Concat(object, object)。此指令的意思是:從 Evaluation Stack 中取出兩個值,此二值皆為 Reference Type,下面的值當作第一個參數,上面的值當作第二個參數,呼叫 mscorlib.dll 所提供的 System.String.Concat() method 來將此二參數進行字串接合(String Concatenation),將接合出來的新字串放在 Managed Heap,將其 Reference 放進 Evaluation Stack。值得注意的是:由於 System.String.Concat() 是 static method,所以此處使用的指令是 call,而非 callvirt(呼叫虛擬)。執行完此道指令之后,記憶體的變化如圖17 所示:

什么是NET中IL(圖文詳解)
圖17

請注意:此時 Managed Heap 中的 Int32(6) 以及 String("i+j+k=") 已經不再被參考到,所以變成垃圾,等待 GC 的回收。

接著要執行第十七道指令 call void [mscorlib] System.Console::WriteLine(string)。此指令的意思是:從 Evaluation Stack 中取出一個值,此值為 Reference Type,將此值當作參數,呼叫 mscorlib.dll 所提供的 System.Console.WriteLine() method 來將此字串顯示在 Console 視窗上。System.Console.WriteLine() 也是 static method。執行完此道指令之后,記憶體的變化如圖18 所示:

什么是NET中IL(圖文詳解) 圖18

接著要執行第十八道指令 ret。此指令的意思是:結束此次呼叫(也就是 Main 的呼叫)。此時會檢查 Evaluation Stack 內剩下的資料,由於 Main() 宣告不需要傳出值(void),所以 Evaluation Stack 內必須是空的,本范例符合這樣的情況,所以此時可以順利結束此次呼叫。而 Main 的呼叫一結束,程式也隨之結束。執行完此道指令之后(且在程式結束前),記憶體的變化如圖19 所示:

什么是NET中IL(圖文詳解) 圖19

通過此范例,讀者應該可以對于 IL 有最基本的認識。對 IL 感興趣的讀者應該自行閱讀 Serge Lidin 所著的《Inside Microsoft .NET IL Assembler》(Microsoft Press 出版)。我認為:熟知 IL 每道指令的作用,是 .NET 程式員必備的知識。.NET 程式員可以不會用 IL Assembly 寫程式,但是至少要看得懂 ILDASM 反編譯出來的 IL 組合碼。

到此,關于“什么是NET中IL(圖文詳解)”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

双柏县| 巩留县| 云梦县| 神池县| 成武县| 万源市| 邻水| 县级市| 黔西县| 广汉市| 巴南区| 大丰市| 左云县| 河东区| 江安县| 庆元县| 满城县| 永顺县| 黑河市| 蓝田县| 娄烦县| 茌平县| 六盘水市| 凤山县| 宁强县| 郓城县| 丰城市| 湖北省| 霍城县| 鄯善县| 白沙| 巨鹿县| 盱眙县| 隆尧县| 和静县| 民乐县| 开远市| 栾川县| 湖口县| 沧州市| 白玉县|