IL and 堆於棧
引用型別:引用型別儲存在堆中。型別例項化的時候,會在堆中開闢一部分空間儲存類的例項。類物件的引用還是儲存在棧中。
值型別:值型別總是分配在它宣告的地方,做為區域性變數時,儲存在棧上;類物件的欄位時,則跟隨此類儲存在堆中。
https://www.cnblogs.com/zd1994/p/4424329.html
http://www.cnblogs.com/kirinboy/archive/2012/06/12/value-and-reference-in-csharp-1.html
關鍵字:.method表示方法的意思,.method private hidebysig static void Main(string[] args) cil managed表示的意思就是static void main(string[] args)
.entrypoint標誌方法的入口
.maxstack表示分配堆疊大小
.locals init中存放的是當前方法的區域性變數,這裡面是string型別,它的名稱叫hello。Init指令表示對變數應以對應的型別預設值進行初始化,通常情況下變數名可以省略,在程式碼中將以零基索引來引用
例如:stloc.0表示將Envaluation Stack中的一個棧頂數值儲存到區域性變數0(Call Stack)中。
先介紹幾個關於MSIL內部知識點:
①.Managed Heap:這是動態配置(Dynamic Allocation)的記憶體,由 Garbage Collector(GC)在執行時自動管理,整個 Process 共用一個 Managed Heap,可以理解為引用型別的東西都放在這個Managed Heap中。
②.Call Stack:這是由 .NET CLR 在執行時自動管理的記憶體,每個Thread都有自己的Call Stack堆疊。每呼叫一次method,就會使得Call Stack上多了一個Record Frame;呼叫完畢之後,此Record Frame會被丟棄。一般來說,Record Frame內記錄著method引數(Parameter)、返回位址(Return Address)、以及區域性變數(Local Variable)。.NET CLR都是使用0, 1, 2…編號的方式來識別區域性變數。
③.Evaluation Stack:這是由.NET CLR在執行時自動管理的記憶體,每個Thread都有自己專屬的Evaluation Stack。壓入的到Evaluation Stack的值,當方法呼叫結束時必須保持這個堆疊的平衡,這裡面存放例如區域性變數值,以及引用型別的地址。
指令ldc是將引數儲存至堆疊Evaluation Stack
指令stloc是將變數儲存至堆疊Call Stack
技巧:ld開頭就是載入資料到Evaluation Stack中,而st開頭就是將Envaluation Stack中的資料儲存到Call Stack,Call Stack存放區域性變數值。
接下來我們將演示程式碼的堆疊情況。