MSIL入门(一)C#代码与IL代码对比
基础概念
Microsoft中间语言(MSIL),也成为通用中间语言(CIL),是一组与平台无关的指令,由特定于语言的编译器从源代码生成。MSIL是独立于平台的,因此,他可以在任何公共语言基础架构支持特定的环境上执行。
通过JIT编译器将MSIL转换为特定计算机环境的特定机器代码。这是在执行MSIL之前完成的,同样,MSIL在需求的基础上转换为机器代码,既JIT编译器根据需要而不是整个MSIL进行编译。
公共语言运行时(CLR)中的执行过程:执行过程包括创建MSIL以及通过JIT编译器将MSIL转换为机器代码,如下所示:

- 在CLR的编译期间,特定于语言的编译器会将源代码转换为MSIL。此外,与MSIL一起,在编译中还会生成元数据。元数据包含诸如代码中类型的定义和签名,运行时信息等信息。
- 通过组装MSIL,可以创建一个公共语言基础结构(CLI)组装。该程序集基本上是用于安全性,部署,版本控制等已编译的代码库,它具有两种类型,进程程序集(EXE)和程序集(DLL)。
- 然后JIT编译器将Microsoft中间语言(MSIL)转换为特定于JIT编译器运行所在的计算机环境的机器代码。MSIL在需求的基础上转换器为机器代码,即JIT编译器根据需要而不是整个MSIL进行编译。
- 然后,由JIT编译器获得的机器代码由计算机的处理器执行。
打印字符串
static void Main(string[] args)
{
Console.WriteLine("HelloWord!");
}
.entrypoint 定义程序的入口点,该函数在程序启动时由.NET运行库调用
.maxstack 定义函数代码所用堆栈的最大深度
.ldstr string把一个字符串常量装入堆栈
call function(parameters)调用静态函数,函数的参数必须在函数调用前装入堆栈
pop 取出栈顶的值,当我们不需要把值存入变量时使用
ret 从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上。
.method private hidebysig static void
Main(
string[] args
) cil managed
{
.entrypoint //主函数,程序的入口
.maxstack 8 //栈的最大深度。
// [8 9 - 8 10]
IL_0000: nop //什么都不做
// [9 13 - 9 45]
IL_0001: ldstr "HelloWord!" //把字符串压入堆栈
IL_0006: call void [System.Console]System.Console::WriteLine(string) //调用WriteLine
IL_000b: nop //什么都不做
// [10 9 - 10 10]
IL_000c: ret //return
} // end of method Program::Main
数据运算
add 2个值相加。命令的参数必须在调用前装入堆栈,该函数从堆栈中移除参数并把运算后的结果压入堆栈。
sub 2个值相减
mul 2个值相乘
static void Main(string[] args)
{
int x = 1;
Console.WriteLine(x * 3 + 1 - 1);
}
.method private hidebysig static void
Main(
string[] args
) cil managed
{
.entrypoint //主函数,程序的入口
.maxstack 2 //栈的最大深度
.locals init (
[0] int32 x,
[1] int32 y,
[2] int32 z //本地变量定义,定义int类型的 x、y、z
)
// [8 9 - 8 10]
IL_0000: nop //什么都不做
// [9 13 - 9 23]
IL_0001: ldc.i4.1 //把x的值放到计算堆栈上
IL_0002: stloc.0 //把计算堆栈顶部的值(x)放到调用堆栈索引0处
// [10 13 - 10 23]
IL_0003: ldc.i4.3 //把z的值放到计算堆栈上
IL_0004: stloc.1 //把计算堆栈顶部的值(y)放到调用堆栈索引1处
// [11 13 - 11 23]
IL_0005: ldc.i4.1 //把x的值放到计算堆栈上
IL_0006: stloc.2 //把计算堆栈顶部的值(z)放到调用堆栈索引2处
// [12 13 - 12 46]
IL_0007: ldloc.0 //把调用堆栈索引为0处的值复制到计算堆栈
IL_0008: ldloc.1 //把调用堆栈索引为1处的值复制到计算堆栈
IL_0009: mul //相乘
IL_000a: ldloc.2 //把调用堆栈索引为2处的值复制到计算堆栈
IL_000b: add //相加
IL_000c: ldloc.2 //把调用堆栈索引为2处的值复制到计算堆栈
IL_000d: sub //相减
IL_000e: call void [System.Console]System.Console::WriteLine(int32) //调用WriteLine
IL_0013: nop //什么都不做
// [13 9 - 13 10]
IL_0014: ret //return
} // end of method Program::Main
Reference
MSIL入门(一)C#代码与IL代码对比的更多相关文章
- 四、CLR执行程序集中代码和IL代码简介
三.加载公共语言运行时中介绍了在安装了.Net Framework中加载公共语言运行时,公共语言运行时加载程序集的过程.以及通过vs stdio设置源码编译的目标平台的过程. 本问主要介绍公共语言加载 ...
- 读懂IL代码(一)
以前刚开始学C#的时候,总有高手跟我说,去了解一下IL代码吧,看懂了你能更加清楚的知道你写出来的代码是如何运行互相调用的,可是那时候没去看,后来补的,其实感觉也不晚.刚开始看IL代码的时候,感觉非常吃 ...
- C#基础拾遗系列之一:先看懂IL代码
一.前言 首先,想说说为什么要写这样系列的文章,有时候在和同事朋友聊天的时候,经常会听到这样的话题: (1)在这家公司没什么长进,代码太烂,学不到东西.(你有没有想想框架为什么这样写,代码还可以怎么去 ...
- 如何解读IL代码
如何解读IL代码 关于IL代码,我有将从三个方面去揭开它神秘的面纱.IL代码是什么?我们为什么要去读懂IL代码?我们如何去读懂IL代码?这三个问题的解答,将是我解读IL代码的整体思路. IL代码是什么 ...
- C# 如何查看源程序的IL代码
1.打开microsoft visual studio 2008 / visual studio tools / visual studio 2008 命令提示 ,并输入ilda ...
- 详解.NET IL代码
一.前言 IL是什么? Intermediate Language (IL)微软中间语言 C#代码编译过程? C#源代码通过LC转为IL代码,IL主要包含一些元数据和中间语言指令: JIT编译器把IL ...
- 用ildasm/ilasm修改IL代码
原文地址:http://www.cnblogs.com/dudu/archive/2011/05/17/ildasm_ilasm_il.html 在开发中遇到这样一个场景,需要修改一个dll文件(.N ...
- 认识IL代码---从开始到现在 <第二篇>
·IL代码分析方法 ·IL命令解析 ·.NET学习方法论 1.引言 自从『你必须知道.NET』系列开篇以来,受到大家很多的关注和支持,给予了anytao巨大的鼓励和动力.俱往昔,我发现很多的园友都把目 ...
- IL代码
浅析.NET IL代码 一.前言 IL是什么? Intermediate Language (IL)微软中间语言 C#代码编译过程? C#源代码通过LC转为IL代码,IL主要包含一些元数据和中间语 ...
随机推荐
- Java实现 LeetCode 4 寻找两个有序数组的中位数
寻找两个有序数组的中位数 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 n ...
- ClickHouse基本操作(一)
常用SQL 创建表 1 2 3 4 5 6 7 CREATE TABLE b6logs( eventDate Date, impid UInt64, uid String, idfa String, ...
- 滴滴HBase大版本滚动升级之旅
桔妹导读:滴滴HBase团队日前完成了0.98版本 -> 1.4.8版本滚动升级,用户无感知.新版本为我们带来了丰富的新特性,在性能.稳定性与易用性方便也均有很大提升.我们将整个升级过程中面临的 ...
- 05.Java面向对象
一.面向对象基本概念 面向对象的特征 封装 封装是指利用抽象数据类型将数据(属性)和对数据的操作(方法)包装起来,把对象的属性和动作结合成一个独立的单位,并尽可能隐蔽对象的内部处理细节. 继承 一个类 ...
- Linux系统命令详解
目录 1. su 1.1. su命令中passwd的自动输入 2. sshpass 3. locate/mlocate 4. top/htop 5. lftp 6. kill/killall 1. s ...
- mail邮件操作
目录 1. 概念 1.1. 常见的类型 1.2. 相关协议 1.3. SMTP协议 2. python::smtplib 1. 概念 1.1. 常见的类型 Mail User Agent 收发邮件用的 ...
- Dorado开发——树形下拉框
最近在学习Dorado开发的过程中,遇到了一个问题,Dorado的树形下拉框选择:Dorado默认情况下父节点和子节点都是可选的,而我要实现的是父节点不可选. 解决办法:在下拉框中,判断父子节点,点击 ...
- Android中的SharedPreferences存储
一.前言 不同于文件的存储方式,SharedPreferences是使用键值对的方式来存储数据的.也就是说,当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把 ...
- cocos2dx Mac平台 打印长字符串,游戏卡死
1,打开了输出控制台,输出卡死的解决方案: 打开控制台: game -console enable 关闭控制台: game -console false 修改文件 ConsoleWindowContr ...
- 深入了解C#(TPL)之Parallel.ForEach异步
前言 最近在做项目过程中使用到了如题并行方法,当时还是有点犹豫不决,因为平常使用不多, 于是借助周末时间稍微深入了下,发现我用错了,故此做一详细记录,希望对也不是很了解的童鞋在看到本文此文后不要再犯和 ...