程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 《C# to IL》第二章 IL基礎(4)

《C# to IL》第二章 IL基礎(4)

編輯:關於C語言

在C#中的關鍵字new,被轉換為匯編器指令newobj。 這就為IL不是一門低級匯編語言並且還可以在內存中創建對象提供了證據。指令newobj在內存中創建了一 個新的對象。即使在IL中,我們也不會知道new或newobj真正做了些什麼。這就證實了IL並不是另一門高 級語言,而是被設計為其它現代語言都能夠編譯為IL這樣一種方式。

使用newobj的規則和調用一 個函數的規則是相同的。函數名稱的完整原型是必需的。在這個例子中,我們調用了無參數的構造函數, 從而函數.ctor會被調用。在構造函數中,WriteLine函數會被調用。

正如我們先前承諾的,這裡 ,我們將要解釋指令ldarg.0。無論何時創建一個對象——一個類的實例,都會包括兩個基本 的實體:

函數

字段或變量,如data

當一個函數被調用時,它並不知道也不關心誰 調用了它或它在哪裡被調用。它從棧上檢索它的所有參數。沒有必要在內存中有一個函數的兩份復制。這 是因為,如果一個類包括了1兆的代碼,那麼每當我們對其進行new操作時,都會占據額外的1兆內存。

當new被首次調用時,會為代碼和變量分配內存。但是之後,在new上的每一次調用,只會為變量 分配新的內存。從而,如果我們有類的5個實例,那麼就只有代碼的一份復制,但是會有變量的5份獨立的 復制。

每個非靜態的或實例函數都傳遞了一個句柄,它表示調用這個函數的對象的變量位置。這 個句柄被稱為this指針。this由ldarg.0表示。這個句柄總是被傳遞為每個實例函數的第1個參數。由於它 總是被默認傳遞,所以在函數的參數列表中沒有提及。

所有的操作都發生在棧上。pop指令移出棧 頂的任何元素。在這個例子中,我們使用它來移除一個zzz的實例,它是通過newobj指令被放置在棧頂的 。

a.cs

class zzz
    {
        public static void Main()
        {
            System.Console.WriteLine("hi");
            new zzz();
        }
        zzz()
        {
            System.Console.WriteLine("bye");
        }
        static zzz()
        {
            System.Console.WriteLine("byes");
        }
    }

a.il

.assembly mukhi {}
.class private auto ansi zzz extends System.Object
{
.method public hidebysig static void vijay() il managed
{
.entrypoint
ldstr "hi"
call void System.Console::WriteLine(class System.String)
newobj instance void zzz::.ctor()
pop
ret
}
.method private hidebysig specialname rtspecialname instance void .ctor() il managed
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ldstr "bye"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}
.method private hidebysig specialname rtspecialname static void .cctor() il managed
{
ldstr "byes"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}
}

Output

byes

hi

bye

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved