详解.NET IL代码
一、前言
IL是什么?
Intermediate Language (IL)微软中间语言
C#代码编译过程?
C#源代码通过LC转为IL代码,IL主要包含一些元数据和中间语言指令;
JIT编译器把IL代码转为机器识别的机器代码。如下图

语言编译器:无论是VB code还是C# code都会被Language Compiler转换为MSIL
MSIL的作用:MSIL包含一些元数据和中间语言指令
JIT编译器的作用:根据系统环境将MSIL中间语言指令转换为机器码
为什么ASP.NET网站第一次运行时会较慢,而后面的执行速度则会相对快很多?
当你第一次运行.NET开发的站点时,CLR会将MSIL通过JIT进行编译,最终转换为执行速度非常快的Native Code。这可以解释。
为什么要了解IL代码?
如果想学好.NET,IL是必须的基础,IL代码是.NET运行的基础,当我们对运行结果有异议的时候,可以通过IL代码透过表面看本质;
IL也是更好理解、认识CLR的基础;
大量的实例分析是以IL为基础的,所以了解IL,是读懂他人代码的必备基础,同时自己也可以获得潜移默化的提高;
二、如何把ILDasm导入到VS中
想要看IL代码需要使用ILDasm工具,工具一般在电脑的
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\ildasm.exe
也可以下载ILSpy:http://ilspy.net/
把ILDasm导入到VS工具中,使用方便,具体如下:工具 - > 外部工具

导入之后,vs工具里面就有ILDasm工具了。以后想看IL代码方便多了。
IL代码通过ILDasm反编译后(左图),ILDasm图标意义(右图)

三、分析IL代码
在分析IL代码之前,要先理解几个概念:

图片来源:https://msdn.microsoft.com/zh-tw/library/dd229210.aspx
Managed Heap(托管堆):这就是NET中的托管堆,用来存放引用类型,它是由GC(垃圾回收器自动进行回收)管理;
Call Stack(调用堆栈):调用堆栈:调用堆栈是一个方法列表,按调用顺序保存所有在运行期被调用的方法。
Evaluation Stack(计算堆栈):每个线程都有自己的线程栈,IL 里面的任何计算,都发生在 Evaluation Stack 上,其实就是一个 Stack 结构。可以 Push,也可以 Pop。
可以对照IL指令:指令列表,一步一步来分析IL代码
1、用C#写一个简单控制台应用程序
using System; namespace ILDemo
{
class Program
{
static void Main(string[] args)
{
int i = ;
int j = ;
int k = ;
int answer = i + j + k;
Console.WriteLine("i+j+k=" + answer);
Console.ReadKey();
}
}
}
2、 用ILDasm打开bin下的.exe文件查看代码,具体IL代码如下:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代码大小 42 (0x2a)
.maxstack
.locals init ([] int32 i,
[] int32 j,
[] int32 k,
[] int32 answer)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: ldc.i4.2
IL_0004: stloc.1
IL_0005: ldc.i4.3
IL_0006: stloc.2
IL_0007: ldloc.0
IL_0008: ldloc.1
IL_0009: add
IL_000a: ldloc.2
IL_000b: add
IL_000c: stloc.3
IL_000d: ldstr "i+j+k="
IL_0012: ldloc.3
IL_0013: box [mscorlib]System.Int32
IL_0018: call string [mscorlib]System.String::Concat(object,
object)
IL_001d: call void [mscorlib]System.Console::WriteLine(string)
IL_0022: nop
IL_0023: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_0028: pop
IL_0029: ret
} // end of method Program::Main
3、会用到的IL指令:
nop:无操作
ret:从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上。
call:调用由传递的方法说明符指示的方法。
box:将值类转换为对象引用,就是装箱,同理可以知道拆箱unbox
ldc.i4.X:把int32的值推送到计算堆栈
stloc.X:把计算堆栈顶部的值放到调用堆栈索引为X处
ldloc.X:把调用堆栈X处的值复制到计算堆栈
4、理解注释后的代码
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint //程序入口
// 代码大小 42 (0x2a)
.maxstack // 计算出计算堆栈的能存几个值 .locals init ([] int32 i,
[] int32 j,
[] int32 k,
[] int32 answer) //定义int32类型的i,j,k,answer IL_0000: nop //无操作 IL_0001: ldc.i4.1 //把i的值放到计算堆栈上
IL_0002: stloc.0 //把计算堆栈顶部的值(i的值)放到调用堆栈索引0处
IL_0003: ldc.i4.2 //把j的值放到计算堆栈上
IL_0004: stloc.1 //把计算堆栈顶部的值(j的值)放到调用堆栈索引1处
IL_0005: ldc.i4.3 //把k的值放到计算堆栈上
IL_0006: stloc.2 //把计算堆栈顶部的值(k的值)放到调用堆栈索引2处 IL_0007: ldloc.0 //把调用堆栈索引为0处的值复制到计算堆栈
IL_0008: ldloc.1 //把调用堆栈索引为1处的值复制到计算堆栈
IL_0009: add //相加
IL_000a: ldloc.2 //把调用堆栈索引为2处的值复制到计算堆栈
IL_000b: add //相加
IL_000c: stloc.3 //把计算堆栈顶部的值(add的值)放到调用堆栈索引3处
IL_000d: ldstr "i+j+k=" //推送对元数据中存储的字符串的新对象引用。
IL_0012: ldloc.3 //把调用堆栈索引为3处的值复制到计算堆栈 IL_0013: box [mscorlib]System.Int32 //装箱
IL_0018: call string [mscorlib]System.String::Concat(object,object) //调用内部方法
IL_001d: call void [mscorlib]System.Console::WriteLine(string) //调用WriteLine
IL_0022: nop //无操作
IL_0023: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() //调用ConsoleKey
IL_0028: pop //无操作
IL_0029: ret //return
} // end of method Program::Main
四、最后
IL是跟我高级架构经理的分享和博客园相关的博客学习总结的,最后留2个题目,也是我的高级架构经理分享中提到的两个好玩的问题,也能看出对IL的掌握的程度

答案后续公布。
详解.NET IL代码的更多相关文章
- 详解.NET IL代码(一)
本文主要介绍IL代码,内容大部分来自网上,进行整理合并的. 一.IL简介 为什么要了解IL代码? 如果想学好.NET,IL是必须的基础,IL代码是.NET运行的基础,当我们对运行结果有异议的时候,可以 ...
- SQL Server 表的管理_关于事务的处理的详解(案例代码)
SQL Server 表的管理_关于事务的处理的详解(案例代码) 一.SQL 事务 1.1SQL 事务 ●事务是在数据库上按照一定的逻辑顺序执行的任务序列,既可以由用户手动执行,也可以由某种数据库程序 ...
- SQL Server 表的管理_关于数据增删查改的操作的详解(案例代码)
SQL Server 表的管理_关于数据增删查改的操作的详解(案例代码)-DML 1.SQL INSERT INTO 语句(在表中插入) INSERT INTO 语句用于向表中插入新记录. SQL I ...
- SQL Server 表的管理_关于表的操作增删查改的操作的详解(案例代码)
SQL Server 表的管理_关于表的操作增删查改的操作的详解(案例代码) 概述: 表由行和列组成,每个表都必须有个表名. SQL CREATE TABLE 语法 CREATE TABLE tabl ...
- SQL Server 表的管理_关于事务操作的详解(案例代码)
SQL Server 表的管理_关于事务操作的详解(案例代码) 1.概念 事务(transaction): 是将多个修改语句组合在一起的方法,这个方法中的所有语句只有全部执行才能正确完成功能.即要么全 ...
- http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误)
http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误) 一.总结 服务器内部错误可能是服务器中代码运行的时候的语法错误或者逻辑错误 二.http500:服务器内部错误案例详解 只是一 ...
- android Json解析详解(详细代码)
JSON的定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据 ...
- SILC超像素分割算法详解(附Python代码)
SILC算法详解 一.原理介绍 SLIC算法是simple linear iterative cluster的简称,该算法用来生成超像素(superpixel) 算法步骤: 已知一副图像大小M*N,可 ...
- SQL Server 表的管理_关于完整性约束的详解(案例代码)
SQL Server 表的管理之_关于完整性约束的详解 一.概述: ●约束是SQL Server提供的自动保持数据库完整性的一种方法, 它通过限制字段中数据.记录中数据和表之间的数据来保证数据的完整性 ...
随机推荐
- Effective Java 51 Beware the performance of string concatenation
Using the string concatenation operator repeatedly to concatenate n strings requires time quadratic ...
- eclipse发布项目时,会自动还原server.xml和content.xml文件
因为Tomcat的端口冲突,导致eclipse发布项目时,失败.于是到server.xml文件中修改端口,重启使用eclipse发布项目,发现依然报端口冲突的错误,其原因时,刚才对server.xml ...
- Web Application Project is configured to use IIS. Unable to access the IIS metabase.(配置为使用IIS Web应用程序xxxx项目。无法访问IIS元数据库。)
这几天重装系统,装了win10,居然用vs2013打开项目出现下面这个提示错误,搞了很久才知道原因: Even though I am an administrator on the machine, ...
- 【原创】大众点评监控平台cat的性能分析
由于工作的原因,或者说我们之前内部监控设计和实现有点不满足现有的研发需求,所以调研了一下大众点评开源出来的cat这一套监控系统. 今天我们就来实验一把,cat的客户端埋点在我们的程序流程中上报数据到c ...
- MyCat 学习笔记 第十一篇.数据分片 之 分片数据查询 ( select * from table_name limit 100000,100 )
1 环境说明 VM 模拟3台MYSQL 5.6 服务器 VM1 192.168.31.187:3307 VM2 192.168.31.212:3307 VM3 192.168.31.150: 330 ...
- 最完整PHP.INI中文版
;;;;;;;;;;;;;;;;;;; 关于php.ini ;;;;;;;;;;;;;;;;;;;; 这个文件必须命名为'php.ini'并放置在httpd.conf中PHPINIDir指令指定的目录 ...
- C标准头文件<assert.h>
<assert.h>定义了两个用来调试程序的宏: assert和NDEBUG,assert用来判断表达式是否为真,如果为真继续执行,如果为假,向stderr输出一条错误消息,并调用< ...
- python 解析json loads dumps
认识 引用模块 重要函数 案例 排序 缩进参数 压缩 参考 认识 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于JavaScript(Standa ...
- mysql、sql server、oracle数据库分页查询及分析(操作手册)
1.mysql分页查询 方式1: select * from table order by id limit m, n; 该语句的意思为,查询m+n条记录,去掉前m条,返回后n条记录.无疑该查询能够实 ...
- POJ 2299 Ultra-QuickSort(线段树入门)
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Description In this problem, you have to ana ...