NET中間語言(IL) 图解
作者:蔡學鏞
2003 年 09 月
.NET CLR 和 Java VM 都是堆疊式虛擬機器(Stack-Based VM),也就是說,它們的指令集(Instruction Set)都是採用堆疊運算的方式:執行時的資料都是先放在堆疊中,再進行運算。Java VM 有約 200 個指令(Instruction),每個指令都是 1 byte 的 opcode(操作碼),後面接不等數目的參數;.NET CLR 有超過 220 個指令,但是有些指令使用相同的 opcode,所以 opcode 的數目比指令數略少。特別注意,.NET 的 opcode 長度並不固定,大部分的 opcode 長度是 1 byte,少部分是 2 byte。
本文章以一個實際的例子,讓你瞭解堆疊式 VM 的運作原理,並對 .NET IL(Intermediate Language)有最基本的領略。
下面是一個簡單的 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 來反組譯 EXE 以觀察 IL。我將 Main() 的 IL 反組譯條列如下,這裡共有十八道 IL 指令,有的指令(例如 ldstr 與 box)後面需要接參數,有的指令(例如 ldc.i4.1 與 add)後面不需要接參數。
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
此程式執行時,關鍵的記憶體有三種,分別是:
- Managed Heap:這是動態配置(Dynamic Allocation)的記憶體,由 Garbage Collector(GC)在執行時自動管理,整個 Process 共用一個 Managed Heap。
- 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… 編號的方式來識別區域變數。
- Evaluation Stack:這是由 .NET CLR 在執行時自動管理的記憶體,每個 Thread 都有自己專屬的 Evaluation Stack。前面所謂的堆疊式虛擬機器,指的就是這個堆疊。
後面有一連串的示意圖,用來解說在執行時此三種記憶體的變化。首先,在進入 Main() 之後,尚未執行任何指令之前,記憶體的狀況如圖 1 所示:
圖 1
接著要執行第一道指令 ldc.i4.1。此指令的意思是:在 Evaluation Stack 置入一個 4 byte 的常數,其值為 1。執行完此道指令之後,記憶體的變化如圖 2 所示:
圖 2
接著要執行第二道指令 stloc.0。此指令的意思是:從 Evaluation Stack 取出一個值,放到第 0 號變數(V0)中。這裡的第 0 號變數其實就是原始碼中的 i。執行完此道指令之後,記憶體的變化如圖 3 所示:
圖 3
後面的第三道指令和第五道指令雷同於第一道指令,且第四道指令和第六道指令雷同於第二道指令。為了節省篇幅,我不在此一一贅述。提醒大家第 1 號變數(V1)其實就是原始碼中的 j,且第 2 號變數(V2)其實就是源碼中的 k。圖 4~7 分別是執行完第三~六道指令之後,記憶體的變化圖:
圖 4
圖 5
圖 6
圖 7
接著要執行第七道指令 ldloc.0 以及第八道指令 ldloc.1:分別將 V0(也就是 i)和 V1(也就是 j)的值放到 Evaluation Stack,這是相加前的準備動作。圖 8 與圖 9 分別是執行完第七、第八道指令之後,記憶體的變化圖:
圖 8
圖 9
接著要執行第九道指令 add。此指令的意思是:從 Evaluation Stack 取出兩個值(也就是 i 和 j),相加之後將結果放回 Evaluation Stack 中。執行完此道指令之後,記憶體的變化如圖 10 所示:
圖 10
NET中間語言(IL) 图解的更多相关文章
- GO語言基礎教程:數組,切片,map
這節課我們來講解數組,切片和map,或許您是從其他語言轉到GO語言這邊的,那麼在其他語言的影響下您可能會不太適應GO語言的數組,因為GO語言把數組給拆分成了array,slice和map,接下來的時間 ...
- GO語言基礎教程:流程控制
在開始一個新的章節之前先來回顧上一篇文章的部份,首先我們來看這段代碼: package main import ( "fmt" ) func main(){ var x,y int ...
- GO語言基礎教程:序章
首先自我介紹一下我自己,我是一個coder,目前主要從事B/S程序開發工作,懂點PHP;ASP;JSP;JS;VB;C;DELPHI;JAVA,另外知道幾個數據庫,除此之外別無所長,那麼我為何會選擇學 ...
- Python 面向導向語言 Object Oriented Programming Language
Pytho 是面向對象的程式語言,舉凡 Literals 值都是 Object.例如: >>> id(38)8791423739696 與 >>> id('ABC' ...
- GO語言基礎教程:數據類型,變量,常量
GO類似PHP,每行的結尾要加分號來結束,不同點在於GO對此並不強制,這一點又像javascript,另外GO的語句塊是用一對大括號來包裹的,但是go要求左大括號必須要在語句的結尾處,不能在行首出現左 ...
- 幾個步驟輕鬆在windows操作系統上搭建GO語言開發環境
1. 首先下载官方GO語言安装包: https://code.google.com/p/go/wiki/Downloads?tm=2 2. 设置 GOPATH 在任意磁盘根目录新建一个文件夹,名字随意 ...
- Ubuntu語言支持爲灰色修復方法
Ubuntu語言支持爲灰色修復方法 在Ubuntu12.04中,在下不知爲何將 語言支持 中 應用到整個系統 和 添加語言 這2個按弄成了灰色,導致ibus不能輸入中文,現在唔將修復方法公告天下: 1 ...
- C/C++語言 - 日常算法 - 蛇形填數
C/C++語言 - 日常算法 - 蛇形填數 日期 : 2019-06-11 問題描述: 在n×n方阵里填入1,2,…,n×n,要求填成蛇形. 例如,n=4时方阵为: 10 11 12 1 9 ...
- GO語言基礎教程:Hello world!
首先簡單地說一下GO語言的環境安裝,從 http://golang.org/dl/ 針對自己的操作系統選擇合適的安裝包,然後下載安裝即可,下載的時候注意別選錯了的操作系統,例如go1.3.1.darw ...
随机推荐
- UVa 101 (模拟) The Blocks Problem
题意: 有n个木块及n个木块堆,初始状态是第i个木块在第i个木块堆上.对应有四种操作,然后输出最终状态. 分析: 用一个vector<int>模拟一个木块堆,进行相应操作即可. #incl ...
- auto make System.map to C header file
#!/bin/bash # auto make System.map to C header file # 说明: # 该脚本主要是将Linux内核生成的System.map文件中的符号.地址存入结构 ...
- 思考之spring的ioc
控制反转 英语:Inversion of control,缩写为IoC 我想很多同学都会思考过这样的一个问题,控制反转,什么地方反转了,是不是翻译的不对? 这里插一句 当年马云借着盖茨的嘴说:“互联网 ...
- Java [leetcode 17]Letter Combinations of a Phone Number
题目描述: Given a digit string, return all possible letter combinations that the number could represent. ...
- 【转】如何把ndk编译出来的可执行文件伪装成so打包到apk中
原文网址:http://jeyechao.iteye.com/blog/2164286 ndk编译出来的共享库,eclipse会自动打包到apk中,而编译出来的可执行文件则不会. 要想可执行文件自动被 ...
- 【转】 当程序崩溃的时候怎么办 part-1
转自:http://www.tairan.com/archives/1006 有这样一种情形:当我们正在快乐的致力于我们的app时,并且什么看都是无比顺利,但是突然,坑爹啊,它崩溃了.(悲伤地音乐响起 ...
- 前端的小Demo——涉及keyCode
以下是我的代码: <!doctype html> <html> <head> <meta charset="utf-8"> < ...
- SQL Server 2008 R2主数据服务安装
SQL Server 2008 R2的主数据服务(Master Data Services,简称MDS)已经放出,目前是CTP版本,微软提供了下载地址: http://www.microsoft.co ...
- Java was started but returned exit code=13 C:\ProgramData\Oracle\Java\javapath\javaw.exe
---------------------------Eclipse---------------------------Java was started but returned exit code ...
- 黑盒测试用例设计方法&理论结合实际 -> 等价类划分
一. 概念 等价类划分法是把程序的输入域划分成若干部分(子集),然后从每个部分中选取少数代表性数据作为测试用例.每一类的代表性数据在测试中的作用等价于这一类中的其他值. 二. 等价类划分的应用 等价类 ...