基础概念

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

https://www.geeksforgeeks.org/cil-or-msil-microsoft-intermediate-language-or-common-intermediate-language/

MSIL入门(一)C#代码与IL代码对比的更多相关文章

  1. 四、CLR执行程序集中代码和IL代码简介

    三.加载公共语言运行时中介绍了在安装了.Net Framework中加载公共语言运行时,公共语言运行时加载程序集的过程.以及通过vs stdio设置源码编译的目标平台的过程. 本问主要介绍公共语言加载 ...

  2. 读懂IL代码(一)

    以前刚开始学C#的时候,总有高手跟我说,去了解一下IL代码吧,看懂了你能更加清楚的知道你写出来的代码是如何运行互相调用的,可是那时候没去看,后来补的,其实感觉也不晚.刚开始看IL代码的时候,感觉非常吃 ...

  3. C#基础拾遗系列之一:先看懂IL代码

    一.前言 首先,想说说为什么要写这样系列的文章,有时候在和同事朋友聊天的时候,经常会听到这样的话题: (1)在这家公司没什么长进,代码太烂,学不到东西.(你有没有想想框架为什么这样写,代码还可以怎么去 ...

  4. 如何解读IL代码

    如何解读IL代码 关于IL代码,我有将从三个方面去揭开它神秘的面纱.IL代码是什么?我们为什么要去读懂IL代码?我们如何去读懂IL代码?这三个问题的解答,将是我解读IL代码的整体思路. IL代码是什么 ...

  5. C# 如何查看源程序的IL代码

    1.打开microsoft  visual  studio  2008  /  visual  studio  tools /  visual  studio  2008 命令提示  ,并输入ilda ...

  6. 详解.NET IL代码

    一.前言 IL是什么? Intermediate Language (IL)微软中间语言 C#代码编译过程? C#源代码通过LC转为IL代码,IL主要包含一些元数据和中间语言指令: JIT编译器把IL ...

  7. 用ildasm/ilasm修改IL代码

    原文地址:http://www.cnblogs.com/dudu/archive/2011/05/17/ildasm_ilasm_il.html 在开发中遇到这样一个场景,需要修改一个dll文件(.N ...

  8. 认识IL代码---从开始到现在 <第二篇>

    ·IL代码分析方法 ·IL命令解析 ·.NET学习方法论 1.引言 自从『你必须知道.NET』系列开篇以来,受到大家很多的关注和支持,给予了anytao巨大的鼓励和动力.俱往昔,我发现很多的园友都把目 ...

  9. IL代码

    浅析.NET IL代码   一.前言 IL是什么? Intermediate Language (IL)微软中间语言 C#代码编译过程? C#源代码通过LC转为IL代码,IL主要包含一些元数据和中间语 ...

随机推荐

  1. Linux目录结构与功能

    在Linux中,一切皆文件.所以,Linux和Windows目录有很大的不同,它没有明确的盘符,它的目录就像一棵大树一样,顶层目录就是根目录:/ ,然后下面又有很多个分支,分支可以再分,从而形成一个庞 ...

  2. requireJS模块化

    1. JavaScript里面js代码的写法:目标是解决冲突和依赖 函数式编程,全局函数和变量--很容易覆盖 对象的写法--也会从外面改变 命名空间:利用名称不同缓冲js代码的冲突---名称太长,不方 ...

  3. 经典文本特征表示方法: TF-IDF

    引言 在信息检索, 文本挖掘和自然语言处理领域, IF-IDF 这个名字, 从它在 20 世纪 70 年代初被发明, 已名震江湖近半个世纪而不曾衰歇. 它表示的简单性, 应用的有效性, 使得它成为不同 ...

  4. ThinkPHP6.0 + Vue + ElementUI + axios 的环境安装到实现 CURD 操作!

    官方文档地址: ​ ThinkPHP6.0: https://www.kancloud.cn/manual/thinkphp6_0/1037479 ​ ElemetUI: https://elemen ...

  5. 对学长TD课程通(.apk)的评价

    界面简介: 界面分为三个部分,第一部分是对课程表的添加,第二部分是对空闲教室的查询,第三部分是实时时间的展示和对软件的评价,实用性很强,仅限于本校学生,界面观赏性较差,从界面上对人的吸引力不够, 实用 ...

  6. WeChair项目Beta冲刺(5/10)

    团队项目进行情况 1.昨日进展    Beta冲刺第五天 昨日进展: 前后端并行开发,项目按照计划有条不絮进行 2.今日安排 前端:扫码占座功能和预约功能并行开发 后端:扫码占座后端逻辑开发,预约用座 ...

  7. java之SFTP上传下载

    import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.ut ...

  8. JavaWeb网上图书商城完整项目--day02-10.提交注册表单功能之页面实现

    1.当从服务器返回的注册错误信息的时候,我们在注册界面需要将错误信息显示出来 我们需要修改regist.jsp页面的代码:其中error是一个haspmap,c标签对map的属性可以直接使用 ${er ...

  9. Spring事务深入剖析--spring事务失效的原因

    之前我们讲的分布式事务的调用都是在一个service中的事务方法,去调用另外一个service中的业务方法, 如果在一个sevice中存在两个分布式事务方法,在一个seivice中两个事务方法相互嵌套 ...

  10. java基础-8种基本类型

    正文 java中的八种基础类型. boolean:只有两个值,false,true 带符号类型 byte:占用1个字节,一个字节也就是8位,那么由于是最高一位是用来表示 负还是正,所以范围就是 -2^ ...