揭开IL代码的神秘面纱--基础篇(一)

2023-11-27 11:20

本文主要是介绍揭开IL代码的神秘面纱--基础篇(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文阅读时长几分钟,让我们一起揭开IL代码的神秘面纱吧。

前言

偶然一次心血来潮,想要了解更深层次的代码运行逻辑,然后就触碰到了IL代码,对于IL代码没了解之前总感觉很神奇,初一看完全不知所云,但是了解IL代码后你能更加清楚的知道你的代码是如何运行的。

1.1  什么是IL

IL是.NET框架中中间语言(Intermediate Language)的缩写。使用.NET框架提供的编译器可以直接将源程序编译为.exe或.dll文件,但此时编译出来的程序代码并不是CPU能直接执行的机器代码,而是一种中间语言IL(Intermediate Language)的代码。

1.2 为什么要了解IL

在很多时候不明白代码是如何操作时就可以通过IL指令来解释,比如,装箱,拆箱是否只是听别人说或者书上讲是怎么怎么实现的,自己是否证实过呢?了解IL指令后,在写代码的时候,你可以很清楚的知道写下的每一行代码,计算机都是如何处理的。

1.3  如何才能玩转IL

IL代码有200多个指令,我们只需要用到其20%的指令就可以解决我们80%的问题了,所以,只要能看懂普通的程序代码编译成的IL代码就行了。

还有就是要多看,一定要多看,IL代码的每一条指令都是特定的意思,看得多了自然就懂了,当对自己代码有疑问时尝试看看它对应的IL代码,也许你会了解得更多。

IL指令大全

IL代码编译器 ILDasm

1.4  如何查看并解读IL

以下说明用例使用的版本是.Net Framework 4.6.1

1、写一段代码。

2、编译通过并生成,在工程目录下找到项目的exe文件,并将其拖到ILDasm工具内

3、双击你想要看的就可以了

接下来,一步一步来。

1、写一段C#代码

        public static void Main(){// 基础测试int num1 = 1;int num2 = 2;int num3 = num1 + num2;Console.WriteLine(num3);}

2、编译通过并生成,在工程目录下找到项目的exe文件,并将其拖到ILDasm工具内

 ILDasm中图标含义

 

3、双击Main函数会得到我们刚刚代码的IL代码。

在看之前,我想先引入一些内容,可以在读IL代码的时候强化记忆下面这张图(可以自己理解后再画一张习惯自己思维方式的一张图),大概了解一下图以后再去看后面的IL代码,结合图,会更快的理解。

Managed Heap::托管堆,这是动态配置(Dynamic Allocation)的记忆体,由 Garbage Collector(GC)在执行时自动管理,整个Process 共用一个。

  Evaluation Stack:计算堆栈,这是由 .NET CLR 在执行时自动管理的记忆体,每个Thread 都有自己专属的Evaluation Stack(类似一个临时存放值类型数据的线程栈)

  Call Stack:这是由 .NET CLR在执行时自动管理的记忆体,每个Thread 都有自己专属的Call Stack。每Call一次method,就会使得Call Stack 上多了一个Record Frame(局部变量列表);call完之后,此Record Frame会被丢弃(Record Frame用于存放初始化数据,后面会看到的.locals init(int32 V_0)指令的参数值如:V_0)

ldc.i4.x:常用IL指令之一,(ld = load)将Int32类型的整数值 x 推送到计算堆栈上。(0 <= x <= 8)更多表示详见IL指令大全

ldloc.x:常用IL指令之一,(ld = load)将Record Frame上的指定索引(x)处的局部变量加载到计算堆栈上。(0 <= x <= 3)更多表示详见IL指令大全

stloc.x:常用IL指令之一,(st = store)从计算堆栈的顶部弹出当前值并将其存储到Record Frame上的指定索引(x)处。(0 <= x <= 3)更多表示详见IL指令大全

好了,一切准备就绪,开始吧,看一下我们得到的IL代码。

上述IL代码中,除开头说到的三个常用指令外,其他的看注释就很明白,不废话了。


总结

本文部分内容参考链接:读懂IL代码就这么简单

好了,以上就是IL入门部分,IL其实不难,平时多看多思考就够了。如有理解错误,还望各位大佬指出,感谢!

我是一个爱思考,爱分享,爱游戏的游戏程序猿,喜欢就点个关注吧。

 

下一篇 《揭开IL代码的神秘面纱--基础篇(二)》​​​​​​​

这篇关于揭开IL代码的神秘面纱--基础篇(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/427566

相关文章

利用Python调试串口的示例代码

《利用Python调试串口的示例代码》在嵌入式开发、物联网设备调试过程中,串口通信是最基础的调试手段本文将带你用Python+ttkbootstrap打造一款高颜值、多功能的串口调试助手,需要的可以了... 目录概述:为什么需要专业的串口调试工具项目架构设计1.1 技术栈选型1.2 关键类说明1.3 线程模

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

使用Python实现全能手机虚拟键盘的示例代码

《使用Python实现全能手机虚拟键盘的示例代码》在数字化办公时代,你是否遇到过这样的场景:会议室投影电脑突然键盘失灵、躺在沙发上想远程控制书房电脑、或者需要给长辈远程协助操作?今天我要分享的Pyth... 目录一、项目概述:不止于键盘的远程控制方案1.1 创新价值1.2 技术栈全景二、需求实现步骤一、需求

Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码

《Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码》:本文主要介绍Java中日期时间转换的多种方法,包括将Date转换为LocalD... 目录一、Date转LocalDateTime二、Date转LocalDate三、LocalDateTim

mysql的基础语句和外键查询及其语句详解(推荐)

《mysql的基础语句和外键查询及其语句详解(推荐)》:本文主要介绍mysql的基础语句和外键查询及其语句详解(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋... 目录一、mysql 基础语句1. 数据库操作 创建数据库2. 表操作 创建表3. CRUD 操作二、外键

Python基础语法中defaultdict的使用小结

《Python基础语法中defaultdict的使用小结》Python的defaultdict是collections模块中提供的一种特殊的字典类型,它与普通的字典(dict)有着相似的功能,本文主要... 目录示例1示例2python的defaultdict是collections模块中提供的一种特殊的字