前言

一般的只有最终的汇编代码才有机器码表示,然一个偶然的机会发现,MSIL(Microsoft intermediate language)作为一个中间语言表示,居然也有机器码,其实这也难怪,计算机里面万物都是二进制,本篇来看下,以下以.Net8 PreView Source Code分析为主。原文:在此处

概括

1.C# And IL

先上C#代码:

static void Main()
{
Program pm=new Program();
GC.Collect();
Console.WriteLine("CeShi JITDUMP");
Console.ReadLine();
}

非常简单的一段代码,把这段代码编译后的DLL导入到微软官方的ILDASM工具里面去,可以看到如下代码:

.method private hidebysig static void  Main() cil managed
{
.entrypoint
// 代码大小 28 (0x1c)
.maxstack 8
IL_0000: newobj instance void Program::.ctor()
IL_0005: pop
IL_0006: call void [System.Runtime]System.GC::Collect()
IL_000b: ldstr "CeShi JITDUMP"
IL_0010: call void [System.Console]System.Console::WriteLine(string)
IL_0015: call string [System.Console]System.Console::ReadLine()
IL_001a: pop
IL_001b: ret
} // end of method Program::Main

这里注意下标号IL_0000的那段代码:

IL_0000:  newobj     instance void Program::.ctor()

以此为例子作为观察。

2.JIT Import IL

来看下JIT把这段IL代码导入后的一个情况

IL to import:
IL_0000 73 04 00 00 06 newobj 0x6000004
IL_0005 26 pop
IL_0006 28 0e 00 00 0a call 0xA00000E
IL_000b 72 01 00 00 70 ldstr 0x70000001
IL_0010 28 0f 00 00 0a call 0xA00000F
IL_0015 28 10 00 00 0a call 0xA000010
IL_001a 26 pop
IL_001b 2a ret

注意到JIT导入这段IL代码之后,多了机器码,多了十六进制的表示。以IL_0000段代码为例

导入之前:

 IL_0000:  newobj     instance void Program::.ctor()

这里newobj之前没有机器码,newobj之后是调用了函数instance void Program::.ctor()。

导入之后:

IL_0000  73 04 00 00 06    newobj       0x6000004

这里很明显看到变化,newobj之前有一连串的机器码:73 04 00 00 06。newobj之后,则有十六进制0x6000004取代了上面的函数调用:instance void Program::.ctor()。

3.分析

那么IL里面的这些机器码和十六进制数值是干什么用的呢?

首先看下机器码:73 04 00 00 06。一个个的看。

首先的0x73,它表示的是:newobj的机器码。它的原型是:

OPDEF(CEE_NEWOBJ, "newobj",VarPop,PushRef,InlineMethod,   IObjModel, 1,0xFF,0x73,CALL)

后面的04 00 00 06这四个字节的机器码可以看做一个整体,小端取值那么它的值是:6000004。

那么这个6000004到底表示什么东西呢?通过ILDASM的快捷键Ctrl+M打开元数据信息,里面可以看到6000004表示的就是.ctor函数的元数据描述,它的原型如下:

Method #2 (06000004)
-------------------------------------------------------
MethodName: .ctor (06000004)
Flags : [Public] [HideBySig] [ReuseSlot] [SpecialName] [RTSpecialName] [.ctor] (00001886)
RVA : 0x00002084
ImplFlags : [IL] [Managed] (00000000)
CallCnvntn: [DEFAULT]
hasThis
ReturnType: Void
No arguments.

那么这段代码

IL_0000  73 04 00 00 06    newobj       0x6000004

的整体意思就很清楚了,73 04 00 00 06里面的73是表示newobj,后面的04 00 00 06表示调用.ctor非静态构造函数。它实际上跟ILDASM里面显示的IL代码是同一个意思,但是因为在内存里面操作,所以它只能是十六进制或者二进制,JIT导入的时候只不过把字母的含义替换成了具体数字的含义。其它的IL代码依次类推。

结尾

作者:江湖评谈

文章首发在公众号(jianghupt)上,欢迎关注

.Net8罕见的技术:MSIL的机器码简析的更多相关文章

  1. [转帖]简析数据中心三大Overlay技术

    简析数据中心三大Overlay技术 http://www.jifang360.com/news/20161010/n225987768.html 搭建大规模的云计算环境需要数据中心突破多种技术难题,其 ...

  2. 简析 .NET Core 构成体系

    简析 .NET Core 构成体系 Roslyn 编译器 RyuJIT 编译器 CoreCLR & CoreRT CoreFX(.NET Core Libraries) .NET Core 代 ...

  3. DiskGenius注册算法简析

    初次接触DiskGenius已经成为遥远的记忆,那个时候还只有DOS版本.后来到Windows版,用它来处理过几个找回丢失分区的案例,方便实用.到现在它的功能越来越强大,成为喜好启动技术和桌面支持人员 ...

  4. 简析.NET Core 以及与 .NET Framework的关系

    简析.NET Core 以及与 .NET Framework的关系 一 .NET 的 Framework 们 二 .NET Core的到来 1. Runtime 2. Unified BCL 3. W ...

  5. Linux 目录结构学习与简析 Part2

    linux目录结构学习与简析 by:授客 QQ:1033553122 ---------------接Part 1-------------- #1.查看CPU信息 #cat /proc/cpuinf ...

  6. XMR恶意挖矿案例简析

    前言 数字货币因其技术去中性化和经济价值等属性,逐渐成为大众关注的焦点,同时通过恶意挖矿获取数字货币是黑灰色产业获取收益的重要途径.本文简析通过蜜罐获取的XMR恶意挖矿事件:攻击者通过爆破SSH获取系 ...

  7. 简析 Tomcat 、Nginx 与 Apache 的区别

    简析 Tomcat .Nginx 与 Apache 的区别 本文讲的是简析 Tomcat .Nginx 与Apache的区别, 经常在用 apache 和 tomcat 等这些服务器,可是总感觉还是不 ...

  8. JDK框架简析--java.lang包中的基础类库、基础数据类型

    题记 JDK.Java Development Kit. 我们必须先认识到,JDK不过,不过一套Java基础类库而已,是Sun公司开发的基础类库,仅此而已,JDK本身和我们自行书写总结的类库,从技术含 ...

  9. Linux网络性能优化方法简析

    Linux网络性能优化方法简析 2010-12-20 10:56 赵军 IBMDW 字号:T | T 性能问题永远是永恒的主题之一,而Linux在网络性能方面的优势则显而易见,这篇文章是对于Linux ...

  10. 痞子衡嵌入式:简析i.MXRT1170 Cortex-M4 L-MEM ECC功能特点、开启步骤、性能影响

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是恩智浦i.MXRT1170上Cortex-M4内核的L-MEM ECC功能. 本篇是 <简析i.MXRT1170 Cortex-M ...

随机推荐

  1. flutter---->flutter orientation

    Get the orientation 1. Media Query import 'package:flutter/material.dart'; void main() => runApp( ...

  2. vue3中watch的写法大合集。

    VUE2的watch是一个属性写法是 watch:{ data1(newVal,oldVal){ 同步/异步操作 } } VUE3的watch则是一个函数,写法是 注意数据必须是响应式的 let nu ...

  3. 一遍博客带你上手Servlet

    概念 Servlet其实就是Java提供的一门动态web资源开发技术.本质就是一个接口. 快速入门 创建web项目,导入servlet依赖坐标(注意依赖范围scope,是provided,只在编译和测 ...

  4. Win系统下的免杀思路(总结非教程)

    1.简介 在安全厂商日趋成熟的背景下,编写免杀马的难度和成本日益增长.好用新兴的开源项目在短时间内就被分析并加入特征库.笔者调研了部分开源项目,其中也有项目做了类似的分析 [1],目前能够免杀的项目初 ...

  5. python从shp文件中读取经纬度数据

    python从shp文件中读取经纬度数据 没有接触过GIS的人来说shp文件很陌生而且很难打开查看,好在python可以从中提取出自己想要的数据 pyshp库的安装 python的pyshp库可以实现 ...

  6. day118:MoFang:根据激活/未激活的状态分别显示树桩&种植植物&解锁树桩&化肥/修剪/浇水/宠物粮小图标数字的显示

    登录 1.根据激活状态和未激活状态分别显示树桩 2.用户使用植物道具进行果树种植 3.解锁树桩 4.化肥/修剪/浇水/宠物粮小图标显示 种植栏的功能实现 1. 客户端需要的植物相关参数: 总树桩数量, ...

  7. Rust中的迭代器的使用:map转换、filter过滤、fold聚合、chain链接

    什么是迭代器 Rust中的迭代器是一种强大的工具,它提供了一种灵活.通用的方法来遍历序列.迭代器是实现了Iterator trait的类型,并需要至少实现一个next函数,用于让迭代器指向下一个迭代对 ...

  8. Linux云计算运维工程师day28shell编程基础

    一. 1.全局变量.环境变量 Export OLDOBY="I am a oldboy."  Echo OLDOBY OLDOBY="I am a oldboy.&quo ...

  9. sqlmap安全测试工具使用简介

    SQLmap是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞,目前支持的数据库是MySQL,Oracle,PostgreSQL,Microsoft  SQL  S ...

  10. 【H5】Emmet 指令 HTML

    Emmet操作指南 HTML篇 生成带有内容的标签 标签名{内容}可以生成带有内容的标签 div{abc} <div>abc</div> 生成带有属性的标签 生成带有class ...