平时工作的时候总是使用ctrl c+ctrl v去快速开发实现业务功能,但是在工作之余,我们也应该要注意静下心来去学习和提高自己。进阶的文章随性来写,不定时更新。希望可以和大家共同学习,共同进步。今天我们一起来理解一下c#的运行机制。

  c#语言具有简单易入门的特点,初学者通常简单拖动几个控件,写几行代码就可以实现一个“程序”了,但是这样也让我们养成了一种依赖c#封装特性的习惯。

  c#是一种高级语言,通过它编写的代码不能被机器识别。在这个被机器识别的过程中:首先是windows加载MSCorEE.dll(一个.NET framework自带的链接库,可在你安装目录找到),主线程会通过调用MSCorEE.dll中的方法来初始化CLR来获取IL(即中间语言),但是,这时候的中间语言仍然不能被识别,还需要 JITCompiler 来将IL编译成可以被机器识别的cpu指令,至此,我们在项目中生成的dll或者exe文件才算是被识别。

  接下来,我们来详细探讨怎么查看这个IL(中间语言)。

 一:在vs2015中增加ILDASM反编译工具

  正所谓,工欲善其事,必先利其器。我们要想学习并且进阶,就要学会运用各类工具。首先,我们将ILDASM加载到宇宙第一开发IDE -- VS中,博主此时使用的是vs2015,因此就以vs2015来作为例子。

  在vs2015中打开工具-->外部工具,点开后选择添加,如图:(一般来说,ILDASM默认地址是:C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools)

  二:反编译后的IL详细解释

在安装了ILDASM后,打开工具就可以看到已经多了一个工具ILDASM

我们在程序中使用这个工具。如下:

首先送上一张图片帮助大家理解

1)双击打开MANIFEST,这是程序的清单文件。红色箭头表示引用的外部文件是mscorlib

.publickeytoken = (标记 ) 指定所引用程序集的实际公钥标记。公钥能唯一确定程序集。

.ver:指定引用程序集的版本

.assembly 表示程序集

 2)打开program的扩展

.class表示的Program是一个类,extends 代表Program类继承于程序集mscorlib中的System.Object类,这就告诉我们,在C#中所有的类的父类都是Object。

private为访问权限,表明该类是私有的。

auto:表明程序加载的时候内存布局是有CLR决定的,而不是由程序本身控制的。

ansi:表明类的编码为ansi编码

beforefieldinit :表明CLR可以在第一次访问静态字段之前的任何时刻执行类型构造函数。类型构造函数也就是构造函数,而使用beforefieldinit属性可以提高性能。

 3)

.ctor 表示构造函数

cil managed 表明方法体中的代码是IL代码,且是托管代码,即运行在CLR运行库中的代码

.maxstack 表明执行构造函数时,评估堆栈可容纳数据项的最大个数。评估堆栈是保存方法中所需变量的值的一个内存区域,该区域在方法执行结束时会被清空,或者存储一个返回值

IL_0000是代码行的开头。一般在IL_标记之前的部分为变量的声明和初始化操作。

ldarg.0表明加载第一个成员参数,其中ldarg是load argument 的缩

call 指令一般用于调用静态方法,而这段代码中call指令并不是在调用静态函数,而是调用System.Object构造函数。另外一个指令则一般用来调用实例方法,它的调用过程是:首先检查被调用的函数是否为虚函数,

如果不是就直接调用,如果是则检查子类是否重写,如果有重写就调用子类中的实现,如果没有重写就继续调用原来函数。

ret 指令表示执行完毕,就是return的缩写

4)看了这么久,终于到达了IL中间语言的Main方法

hidebysig :指令表示如果当前类作为父类,用该指令标记的方法将不会被子类继承

.entrypoint :指令代表该函数是程序的入口函数,每个托管应用程序都有且只有一个入口函数,CLR加载的时候,首先从.entrypoint函数开始执行。

.locals init ([0] int32 i1,[1] int32 i2)

表示定义int类型的变量,变量名称是:i1,i2

IL_0000: nop示不做任何操作 No Operation

IL_0001:ldc.i4.1:此指令的意思是:在 Evaluation Stack 置入一個个4 byte 的常数:  

stloc.0  :从计算堆栈的顶部弹出当前值并将其存储到索引 0 处的局部变量列表中,在此示例中:stloc.0。此指令的意思是:从 Evaluation Stack 取出一個值,放到第 0 号变数(V0)中

ldloc.0 :将索引 0 处的局部变量加载到计算堆栈上。也就是:把变量helloString 加载到计算堆栈上(以ld为前缀的指令表示:入栈操作  st为前缀的指令则代表着出栈操作)

ldloc.1:同上,将索引 1处的局部变量加载到计算堆栈上。

add:增加两个变量的值

ret:返回结果。

c#进阶一:使用ILDASM来查看c#中间语言的更多相关文章

  1. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_通过ILDasm.exe查看编译器如何将类型及其成员编译成元数据

    [实例代码] using System; public sealed class SomeType //-------------1 { //嵌套类 private class SomeNestedT ...

  2. 我的Android进阶之旅------>Android中查看应用签名信息

    一.查看自己的证书签名信息 如上一篇文章<我的Android进阶之旅------>Android中制作和查看自定义的Debug版本Android签名证书>地址:http://blog ...

  3. [Xcode 实际操作]九、实用进阶-(21)使用“调试视图”查看各界面元素的层次顺序

    目录:[Swift]Xcode实际操作 本文将演示如何在程序运行期间,查看模拟器各界面元素的层次顺序. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import ...

  4. 【过程改进】10分钟进阶Nuget

    目录 nuget初识 nuget本地包 nuget解决依赖冲突 nuget是什么 .net版的maven(java)? 如果你用过windows的chocolatey,mac的homebrew或许更容 ...

  5. 10分钟进阶Nuget

    nuget是什么 .net版的maven(java)? 如果你用过windows的chocolatey,mac的homebrew或许更容易理解他,先来回顾下以前我们是如何处理或者碰到过的问题. 1.假 ...

  6. linux 进阶命令

    进阶命令 1    df指令   查看磁盘的空间 # df -h    -h表示可读性更高,方便读取 执行指令后(Filesystem:磁盘名称  size:磁盘总大小  Used: 被使用的大小  ...

  7. 在 visual studio 中添加 ILDASM 工具

    先写下一般的用法,就是在 vs 中添加 ILDASM 工具. 添加步骤: 工具---->外部工具----->添加: 标题我一般取为 ILDASM,命令那一栏是要选择 ILDASM 的路径, ...

  8. Django笔记&教程 5-2 进阶查询——Queryset

    Django 自学笔记兼学习教程第5章第2节--进阶查询--Queryset 点击查看教程总目录 Queryset相关内容其实蛮多的,本文只介绍一些常用的,详细的推荐查询官方文档:queryset-a ...

  9. 如何重载delegate

    在写delegate的时候遇到一个问题,在已有一个不带参数的delegate基础上,试图再增加一个带参数的delegate,结果VS报了“already contains a definition f ...

随机推荐

  1. 发送email

    package com.rjj.d; import java.security.GeneralSecurityException; import java.util.Date; import java ...

  2. 为啥程序会有bug?

    如果这是第二次看到我的文章,欢迎右侧扫码订阅我哟~ 

  3. Telerik控件集-2019.R1.SP1.All

    Telerik 专注于微软.Net平台的表示层与内容管理控件,提供高度稳定性和丰富性能的组件产品DevCraft,并可应用在非常严格的环境中.Telerik拥有 Microsoft, HP, Alco ...

  4. Spring Boot 2.0 WebFlux 教程 (一) | 入门篇

    目录 一.什么是 Spring WebFlux 二.WebFlux 的优势&提升性能? 三.WebFlux 应用场景 四.选 WebFlux 还是 Spring MVC? 五.异同点 六.简单 ...

  5. [区块链] 密码学——Merkle 树

    在计算机领域,Merkle树大多用来进行完整性验证处理.在处理完整性验证的应用场景中,特别是在分布式环境下进行这样的验证时,Merkle树会大大减少数据的传输量以及计算的复杂度. Merkle哈希树是 ...

  6. matplotlib种类

    matplotlib模板: 1:线图 plot()单线段图 2:多个线图 subplot()Multiple axes (i.e. subplots) are created with the sub ...

  7. 原生js查询、添加、删除类

    1.添加类 为标签添加一个class的类 如:<div id="box" class="box">内容</div> document.g ...

  8. 图解CSS3-flex布局

    前言 最近笔者在复习以前基础知识,发现很多细的知识点还是需要重新再总结一番.本文对flex布局进行图解说明,以后忘了的同学可以随时过来查看,欢迎转载,烦请注明出处. 主体 万丈高楼平地起,熟悉flex ...

  9. NumPy的基本用法

    NumPy简介:NumPy是高性能科学计算和数据分析的基础包.是pandas等其他各种工具的基础NumPy主要功能:ndarray,一个多维数组结构,高效且节省空间无需循环对数组数据进行快速运算的数学 ...

  10. TensorFlow 2.0 Alpha pip安装指令

    TensorFlow 2.0 Alpha目前已经可以通过pip安装,亲测有效,安装指令为: # 普通版本 pip install tensorflow==2.0.0-alpha0 # GPU版本 pi ...