程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .NET CIL系列第二篇:入棧和出棧——CIL基於棧的本質

.NET CIL系列第二篇:入棧和出棧——CIL基於棧的本質

編輯:關於.NET

在上一篇.NET CIL第一篇:CIL介紹和入門中我們簡要介紹了CIL編程的本質,和學習CIL編程的價值。還介紹了CIL的指令、特性和操作碼。接下來的文字中會頻繁出現:指令、特性、操作碼這些關鍵字。所以請確定你已經知道它們的含義了。

入棧和出棧:CIL基於棧的本質

像C#這樣的高級.NET語言,總是試圖盡量隱藏底層的實現。.NET開發一個不太為人注意的方面就是CIL實際上是一個完全以棧為基礎的開發語言。回憶我們熟悉的System.Collections命名空間中的Stack類型的功能,它被用於壓一個值入棧,同時也能將棧頂的值彈出以供使用。當然,CIL開發人員不是使用System.Collection.Stack來實現入棧和出棧的,不過從思路上是相通的。

正式地說,在CIL中用來負責這個棧實現的部分叫做虛擬執行棧(virtual execution stack)。從下面的介紹中,你將看到CIL提供了一系列操作碼來完成壓入值到這個棧中,這個過程的術語叫加載(load)。同時,CIL也定義了一系列操作碼來將棧頂的值移到內存中(例如局部變量),這個過程的術語叫存儲(store)。

CIL不允許直接訪問一個數據,包括局部變量、方法中傳入的變量或者類型的字段數據。為了實現訪問,必須顯示地加載數據到棧中,並在使用時彈出。請留心這一點,因為這能夠解釋為什麼CIL代碼看起來有些冗余。

下面通過一段簡單的沒有參數和返回值的函數PrintMessage(),來理解CIL是如何應用棧這個模型的。在實現這個方法時,我們只將一個局部的字符串變量輸出到標准的輸出流。

public void PrintMessage()

{

    string myMessage = "Hello";

    Console.WriteLine(myMessage);

}

如果你觀察過C#編譯器是如何將這個方法翻譯成CIL的,將會首先看到PrintMessage()方法用.locals指令為局部的字符串定義了一個存儲空間。接著,這個局部的字符串通過ldstr和stloc.0被加載和存儲到這個局部變量中。(stloc.0可以這樣理解:存儲當前的值到索引為0的局部變量。)

這個索引0處的值接著通過ldloc.0(加載索引為0的局部參數)被夾在到內存來供System.Console.WriteLine()方法使用(通過call操作碼指定)。最後,這個方法以ret操作碼結束返回,以下是PrintMessage()方法的CIL代碼:

.method public hidebysig instance void PrintMessage() cil managed

    {

     // Code size       15 (0xf)

     .maxstack 1

     //定義一個局部的字符串變量(在索引0處)。

     .locals init ([0] string myMessage)

     IL_0000: nop

     //加載一個值為"Hello"的字符串。

     IL_0001: ldstr      "Hello"

     //存儲字符串的值到棧上的局部變量。

     IL_0006: stloc.0

     //調用索引0處的值。

     IL_0007: ldloc.0

     //使用當前的值調用方法。

     IL_0008: call       void [mscorlib]System.Console::WriteLine(string)

     IL_000d: nop

     IL_000e: ret

    } // end of method HelloProgram::PrintMessage

說明:正如我們所看到的,CIL支持使用雙斜槓的注釋語法(也支持/*…*/這個語法)。同C#一樣,注釋將被編譯器完全忽略。

今天的內容比較少,但是比較抽象。今天反復出現:指令、特性、操作碼等這些概念。所以請確保您知道它們的含義,或者查看.NET CIL第一篇:CIL介紹和入門來回憶一下。本來打算發兩篇,因為這篇實在是太短了,今天由於同學來看我,所以下一篇放在凌晨吧。至此我們對CIL基礎知識的介紹告一段落,下一篇將來研究CIL編程的實際使用。千萬不要錯過啊!

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