代码大全 MSIL语言程序设计

.NET平台的编译器会将高级语言(C#,VB.NET,F#)编译成MSIL(微软中间语言)格式。熟悉MSIL语言,可以读懂一些加密程序混淆过的算法,这些算法几乎不能还原成高级语言,但是可以还原成MSIL语言。也可以知道一些高级语言之外的关于CLR的特性,比如多模块程序集,全局静态方法等等。一些.NET保护加密程序也是运用MSIL平台的特性。

阅读本篇文章,假设您已经对这个语言有基本的了解,我会列举这个语言的基本语言应用例子,供参考。

1 Hello world

.method static void main()
{.entrypoint.maxstack 1ldstr "Hello world!"call void [mscorlib]System.Console::WriteLine(string)ret
}

在控制台上打印Hello world字符串。MSIL以entrypoint表示入口方法,而不一定是C#中规定的Main方法。

2 使用局部变量

.locals init (int32 first,int32 second,int32 result)

上面的语法,定义了三个局部变量,它的名称分别是first,sencond,result。

下面的代码读取用户在控制台上的输入值,并调用Parse方法,把结果保存在first局部变量中。

ldstr "First number: "
call void [mscorlib]System.Console::Write(string)
call string [mscorlib]System.Console::ReadLine()
call int32 [mscorlib]System.Int32::Parse(string)
stloc first
 

调用add方法,将frist和second的值加起来,保存到resutl局部变量中

ldloc first
ldloc second
add
stloc result
 

最后,在控制台上打印结果值

ldstr "{0} + {1} = {2}"
ldloc first
box int32
ldloc second
box int32
ldloc result
box int32
call void [mscorlib]System.Console::WriteLine(string, object, object, object)

因为三个局部变量是int32类型,调用WriteLine方法时要传入object类型,所以要装箱(box)。

 

3 定义类型

新建一个calss/enum/struct即为定义一种新的程序类型,扩展.NET本身已有的类型和功能。

.class Kerr.RealEstate.House
{.method public void .ctor(){.maxstack 1ldarg.0 // push "this" instance onto the stackcall instance void [mscorlib]System.Object::.ctor()ret}
}

定义一个静态类型

.class abstract sealed Kerr.RealEstate.MortgageCalculator
{/* members */ 
}

注意下面的代码,它展示了MSIL命名空间的用法。可以直接把calss放在namespace里面,用大括号括起来,或是像本段的第一个代码所表达的,直接写完整的命名空间(C#中不支持这样的写法)。

.namespace Kerr.RealEstate
{.class abstract sealed MortgageCalculator{/* members */ }
}

下面的代码演示新定义的类型继承于现有的类型,和Java的语法相似。

.class Kerr.RealEstate.RoomListextends [System.Windows.Forms]System.Windows.Forms.ListViewimplements Kerr.IView
{/* members */
}

定义一个接口,然后实现这个接口

.class interface Kerr.IView
{/* members */ 
}
.class Kerr.RealEstate.HouseDataextends [mscorlib]System.ValueType
{/* members */
}

 

4  定义类型成员

我在学习C++时,C++把类型成员区分为数据成员和方法成员,前者表示字段,后者表示方法。标准的C++书籍中从来不会把方法称作函数,所以一直以来养成习惯,函数只用来指SQL Server脚本中的函数,.NET代码中只有方法。

假设,我们正在定义下面的类型,将要为它添加方法

.class abstract Kerr.Sample.Object
{
}

静态构造方法和构造方法

.method static void .cctor()
{.maxstack 1ldstr ".cctor"call void [mscorlib]System.Console::WriteLine(string)ret
}
.method public void .ctor()
{.maxstack 1ldarg.0call instance void [mscorlib]System.Object::.ctor()ldstr ".ctor"call void [mscorlib]System.Console::WriteLine(string)ret
}

静态构造方法的调用时机时,当该类型的成员第一次被调用之前,先调用静态构造方法。

创建类型的实例,并存储在局部变量obj中

.locals (class TypeName obj)
newobj void TypeName::.ctor()
stloc obj

定义静态方法

.method static void StaticMethod() { /* impl */ }

定义实例方法

.method void InstanceMethod() { /* impl */ }
 
下面的代码演示如何调用静态方法和实例方法
call void TypeName::StaticMethod()
ldloc obj
call instance void TypeName::InstanceMethod()

定义虚拟方法,这种情况主要用在继承层次中,动态调用继承层次中重写的方法

.class House
{.method public virtual void Buy(){.maxstack 1ldstr "House::Buy"call void [mscorlib]System.Console::WriteLine(string)ret}/* etc */
}
.class TownHouseextends House
{.method public virtual void Buy(){.maxstack 1ldstr "TownHouse::Buy"call void [mscorlib]System.Console::WriteLine(string)ret}/* etc */
}

下面的代码演示了多态的应用,MSIL版本,请参考下面代码

newobj instance void House::.ctor()
stloc house
newobj instance void TownHouse::.ctor()
stloc townHouse
ldloc house
call instance void House::Buy()
ldloc townHouse
call instance void TownHouse::Buy()
ldloc townHouse
call instance void House::Buy()
ldloc townHouse
callvirt instance void House::Buy()

最后在控制台上的输入结果是

House::Buy
TownHouse::Buy
House::Buy
TownHouse::Buy


 

5  异常处理

MSIL是一种面向对象的语言,它的异常处理的基本指令格式

.try
{/* protected code */leave.s _CONTINUE
}
<exception handler>
_CONTINUE:

来看一个例子,它读取字符串值,调用Int32.Parse分析字符串,返回字符串代表的整型值

.try
{ldstr "I'm not a number"// ldnull// ldstr "123"call int32 [mscorlib]System.Int32::Parse(string)leave.s _CONTINUE
}
catch [mscorlib]System.ArgumentNullException
{callvirt instance string [mscorlib]System.Exception::get_Message()call void [mscorlib]System.Console::WriteLine(string)leave.s _CONTINUE
}
catch [mscorlib]System.FormatException
{callvirt instance string [mscorlib]System.Exception::get_Message()call void [mscorlib]System.Console::WriteLine(string)leave.s _CONTINUE
}

上面的代码会抛出格式异常,异常会被FormaException截获,它会在控制台上打印异常信息。

异常过滤器

.try
{// ldstr "I'm not a number"ldnull// ldstr "123"call int32 [mscorlib]System.Int32::Parse(string)leave.s _CONTINUE
}
filter
{ldstr "filter evaluation\n\t"call void [mscorlib]System.Console::Write(string)callvirt instance string [mscorlib]System.Exception::get_Message()call void [mscorlib]System.Console::WriteLine(string)ldc.i4.1endfilter
}
{ldstr "filter handler\n\t"call void [mscorlib]System.Console::Write(string)callvirt instance string [mscorlib]System.Exception::get_Message()call void [mscorlib]System.Console::WriteLine(string)leave.s _CONTINUE
}

try 语句中的代码会抛出null异常,过滤器拦截此异常,并把true压入堆栈,表示已经处理此异常,方法返回。

finally语句用最终都会被执行,比如要释放非托管资源,数据库连接等等

.try
{/* protected code */leave.s _CONTINUE
}
finally
{/* cleanup code */endfinally
}

fault处理语句,try语句执行完毕后,进入fault语句,只能与try语句块一起使用。与C#中的using(using(Object i=new Ojbect()); )用法相似,保证Dispose方法一定会被调用。

.try
{/* protected code */leave.s _CONTINUE
}
fault
{/* cleanup code */endfault
}

6 控制流程

IF-ELSE语句

C#方法定义如下

void Send(string message)
{if (null == message){throw new ArgumentNullException("message");}/* impl */
}

 

翻译成MSIL语言,代码如下

.method void Send(string message)
{.maxstack 2ldnullldarg messageceqldc.i4.0ceqbrtrue.s _CONTINUEldstr "message"newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string)throw_CONTINUE: /* impl */ret
}

FOR语句

C#语句的写法

for (int index = 0; 10 != index; ++index)
{Debug.WriteLine(index);
}

翻译成MSIL语言的写法

    int index = 0;goto _CONDITION;_LOOP:++index;_CONDITION:if (10 != index){// for statementsDebug.WriteLine(index);goto _LOOP;}

再来看一个FOR语句的例子

    .locals init (int32 index)br.s _CONDITION_LOOP:ldc.i4.1ldloc indexaddstloc index _CONDITION:ldc.i4.s 10ldloc indexbeq _CONTINUE// for statementsldloc indexbox int32call void [System]System.Diagnostics.Debug::WriteLine(object)br.s _LOOP_CONTINUE:
 

7 类型转换

MSIL代码例子,请看下面的代码

.locals init (int32 small,int64 big)// Int32 small = 123;
ldc.i4.s 123
stloc small// Int64 big = small;
ldloc small
conv.i8
stloc big// small = static_cast<Int32>(big);
ldloc big
conv.i4
stloc small

对应的C#语句是

Int32 small = 123;
Int64 big = small;small = static_cast<Int32>(big);

逐语句的对比分析

.locals init (int32 small,int64 big)// Int32 small = 123;
ldc.i4.s 123
stloc small// Int64 big = small;
ldloc small
conv.i8
stloc big// small = static_cast<Int32>(big);
ldloc big
conv.i4
stloc small

8  FOREACH语句

FOREACH语句应该是C#发明的,未见其它语言有此语言,以安全快速的方法遍历一个集合。

来看下面的这个例子,C++语言的例子

array<int>^ numbers = gcnew array<int> { 1, 2, 3 };for each (int element in numbers)
{Console::WriteLine(element);
}

翻译成MSIL语言之后,代码如下面所示

   .locals init (int32[] numbers,int32 index)// Create the arrayldc.i4.3newarr int32stloc numbers// Populate the arrayldloc numbers ldc.i4.0 // indexldc.i4.1 // valuestelem.i4ldloc numbers ldc.i4.1 // index ldc.i4.2 // value stelem.i4ldloc numbers ldc.i4.2 // index ldc.i4.3 // valuestelem.i4br.s _CONDITION_LOOP:ldc.i4.1ldloc indexaddstloc index _CONDITION:ldloc numbersldlenldloc indexbeq _CONTINUE// for each statementsldloc numbersldloc indexldelem.i4call void [mscorlib]System.Console::WriteLine(int32)br.s _LOOP_CONTINUE:

再来看稍微复杂一点的例子

Collections::ArrayList numbers(3);
numbers.Add(1);
numbers.Add(2);
numbers.Add(3);for each (int element in %numbers)
{Console::WriteLine(element);
}

翻译成MSIL语言的代码如下面所示

   .locals init (class [mscorlib]System.Collections.ArrayList numbers,class [mscorlib]System.Collections.IEnumerator enumerator)// Create the arrayldc.i4.3newobj instance void [mscorlib]System.Collections.ArrayList::.ctor(int32)stloc numbers// Populate the arrayldloc numbers ldc.i4.1 box int32callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)popldloc numbers ldc.i4.2 box int32callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)popldloc numbers ldc.i4.2 box int32callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)pop// Get the enumeratorldloc numberscallvirt instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator()stloc enumeratorbr.s _CONDITION_CONDITION:ldloc enumeratorcallvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()brfalse.s _CONTINUE// for each statementsldloc enumeratorcallvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current()call void [mscorlib]System.Console::WriteLine(object)br.s _CONDITION_CONTINUE:

 

Visual Studio不支持MSIL格式的源代码文件语法高亮,推荐用Visual Microsoft Intermediate Language编辑器来阅读IL代码,工程化的管理方式,还可生成目标文件,比记事本方便好用。

image

转载于:https://www.cnblogs.com/JamesLi2015/p/3174196.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/433383.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

以太网交换机

以太网交换机是基于以太网传输数据的交换机&#xff0c;以太网采用共享总线型传输媒体方式的局域网。以太网交换机的结构是每个端口都直接与主机相连&#xff0c;并且一般都工作在全双工方式。交换机能同时连通许多对端口&#xff0c;使每一对相互通信的主机都能像独占通信媒体…

待办事项桌面插件_让浏览器重获整洁——标签页管理插件:OneTabOneTab PlusToby...

1 什么是标签页管理插件chrome浏览器虽然为用户提供了一个非常方便的打开新标签页的方法&#xff0c;但是随着用户浏览网页的时间增长&#xff0c;用户在一个chrome窗口中打开的标签页会越来越多&#xff0c;当这些标签页过多的时候&#xff0c;用户在标签页之间进行切换就会变…

关机时无人照管更新正在运行_了解iOS13.1后,在决定更新

苹果提前发布了首个重要更新的iOS 13.1&#xff0c;补充了多个 iOS 13 首发时缺失的重要新功能&#xff0c;可以说 iOS 13.1 才是【真正】的 iOS 13 系统。苹果发布iOS13.1,都更新了哪些内容&#xff1f;iOS13.1修复问题和改进问题&#xff1a;?信息中拟我表情可能无法正确跟踪…

山西计算机网络技术专升本分数线_2020山西成考专升本招生补录第一批公告!附补录院校专业缺额表!...

☞回复【成绩】查询2020年成人高考成绩☞回复【录取】查询20成考录取结果☞回复【补录】查询最新院校缺额信息☞加入学历备考交流群 550985358 专升本第一阶段补录通知与院校缺额信息 达线未被录取&#xff1f;还有机会2020山西成考专升本招生征集志愿第一阶段公告发布12月9日1…

网页编码就是那点事

编码一直是让新手头疼的问题&#xff0c;特别是 GBK、GB2312、UTF-8 这三个比较常见的网页编码的区别&#xff0c;更是让许多新手晕头转向&#xff0c;怎么解释也解释不清楚。但是编码又是那么重要&#xff0c;特别在网页这一块。如果你打出来的不是乱码&#xff0c;而网页中出…

Linux C 中字符串化操作符#

1 #include <stdio.h>2 3 #define dprint( expr ) printf( "%s %d \n", #expr , expr)4 5 int main(void)6 {7 int x 100;8 int y 2;9 10 dprint(x/y); 11 dprint( xy ); 12 dprint( xy2 ); 13 return 0; 14 } 打印信息&…

U-BOOT之一:BootLoader 的概念与功能

U-BOOT之一&#xff1a;BootLoader 的概念与功能 ——转自《U-BOOT移植S3C2440完全手册》 1.1嵌入式Linux 软件结构与分布 一般情况下嵌入式Linux 系统中的软件主要分为以下几部分&#xff1a; 1) 引导加载程序&#xff1a;其中包括内部ROM 中的固化启动代码和BootLoader 两部分…

java写七彩文字_【PS精选案例教程】创建一个漂亮的七彩文字

原标题&#xff1a;【PS精选案例教程】创建一个漂亮的七彩文字效果图&#xff1a;步骤1. 新建一个文档(大小随意)步骤2. 滤镜→渲染→云彩步骤3. 可以按CtrlAltF增加效果步骤4. CtrlJ复制一层步骤5.设置前景色步骤6. 用径向渐变从中间往外拉一个渐变步骤7. 设置“图层1”混合模…

容斥原理的二进制实现模版

最近学习容斥原理&#xff0c;实现容斥原理大致有三种方法&#xff1a;dfs&#xff0c;队列数组&#xff0c;二进制。 今天主要讲下二进制实现容斥原理&#xff1a; 有一个集合{A1……An}&#xff0c;求集合的子集&#xff1f;很显然答案为 也就是2^n个&#xff0c;也就是每一个…

测试鼠标双击_鼠标环境可靠性测试是什么

鼠标和电脑是的组合&#xff0c;购买电脑时一般商家会送给用户一个配套的鼠标&#xff0c;鼠标和电脑一样&#xff0c;对环境的要求较高&#xff0c;极少部分的鼠标由于短路或者是环境温度过高的问题会导致鼠标出现自燃的现象&#xff0c;如果用户此时正在使用电脑编辑文件&…

virtualbox主机网络管理 未能创建_如何在 VirtualBox 中增加现有虚拟机的磁盘大小 | Linux 中国...

导读&#xff1a;你可以在 VirtualBox 中扩大虚拟硬盘&#xff0c;即使在创建之后也可以。                   本文字数&#xff1a;1434&#xff0c;阅读时长大约&#xff1a;2分钟https://linux.cn/article-12869-1.html作者&#xff1a;Dimitrios Savvopoulos译者…

usb长包数据结束判断_如何判断南桥好坏 判断南桥好坏方法介绍【详解】

南桥是电脑里重要的零部件&#xff0c;南桥芯片主要是负责I/O接口等一些外设接口的控制、IDE设备的控制及附加功能等等。那么南桥发生故障&#xff0c; 怎么判断南桥好坏 呢?一、通过测PCI槽、AGP槽对地打阻值可判定南北桥有无损坏1、PCI槽中所有的AD复合线对地打阻值都为300&…

taskkill无法终止进程 拒绝访问_解决删除文件时,提示无法删除的问题

有时我们想删除某个程序文件夹&#xff0c;或是卸载后残留的一些 .dll 等后缀的文件&#xff0c;却一直提示 “运行中” 、 “权限不足” &#xff0c;甚至用第三方的强力删除功能都无法删除。这时我们可以用系统自带的命令行功能&#xff0c;使用几个简单的小命令就可以彻底删…

擦窗机器人测试标准_擦窗机器人,我选择玻妞的三个理由!

很多人都喜欢高层&#xff0c;一览无遗&#xff0c;广阔风景&#xff01;可现实是无论什么高层湖景都会被窗户上日积月累的灰尘遮挡的严严实实&#xff0c;每次擦窗都累到怀&#xff01;疑&#xff01;人&#xff01;生&#xff01;于是一年又一年&#xff0c;你想要的风景始终…

Oracle客户端与java_Oracle 谈 JavaFX 及 Java 客户端技术的未来

原标题&#xff1a;Oracle 谈 JavaFX 及 Java 客户端技术的未来据 Oracle 博客称&#xff0c;从 JDK 11 开始&#xff0c;Oracle 将从 JDK 中删除 JavaFX&#xff0c;但在 2022 年之前&#xff0c;Oracle 还会继续为 JDK 8 中的 JavaFX 提供商业支持。2011 年&#xff0c;JavaF…

低代码开发平台_低代码开发平台测评——伙伴云

​本次测评的产品严格来说不算低代码开发平台&#xff0c;它自己给自己的定位更多是全流程数据生产力平台。不过它依然具备应用搭建的关键要素&#xff0c;而且在数据管理方面还比较出彩&#xff0c;所以不能放过它——伙伴云&#xff0c;这款由Discuz&#xff01;主创团队操刀…

oracle对某两列求和再求和_函数实战:多列条件求和

今天和新手小伙伴们分享有关条件求和的内容&#xff0c;高手请忽略哈。先来看一组销售数据&#xff0c;是某商场不同品牌电视机的三天销售记录&#xff1a;现在需要根据G列的品牌&#xff0c;计算其三天的销售总和。想必有表亲已经想到办法了&#xff0c;既然是按条件求和&…

php 访问第三方接口吗,PHP-----------HTTP请求的第三方接口

2019独角兽企业重金招聘Python工程师标准>>>开发中常常遇到接口请求这个功能&#xff0c;后台也不例外&#xff0c;因为遇到了&#xff0c;所以写一篇。前段时间做商城后台时&#xff0c;需要用到第三方物流接口查询物流信息。post&#xff1a;/***** param $url* par…

(IOS)截图Demo

思路是建一个UIView的子类&#xff0c;获取划动出的矩形&#xff0c;用协议将矩形传递给代理对象&#xff0c;依据该矩形完成图像数据的截取&#xff0c;并显示出来。 截图视图类&#xff1a; #import <UIKit/UIKit.h>protocol UICutImgDelegate;interface BIDCutView : …

POJ1033 Defragment

题目来源&#xff1a;http://poj.org/problem?id1033 题目大意&#xff1a; 某操作系统的文件系统中&#xff0c;所有的磁盘空间被分为N个大小相等的cluster&#xff0c;编号1至N。每个文件占用一个或多个cluster。所有没有被文件占用的cluster称为是空闲的。磁盘上的一个文件…