MSIL实用指南-数学运算】的更多相关文章

C#支持的数学运算是加.减.乘.除.取模,它们对应的指令是Add.Sub.Mul.Div.Rem. 这五个运算都需要两个参数,它们的通用步骤1.生成加载左边变量2.生成加载右边变量3.生成运算指令 实例: ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Sub); 完整的程序如下: using System; using System.Reflection…
数值的比较就是大于.小于.等于.大于等于.小于等于.不等于,它们的运算结果都是布尔值.大于.小于.等于有直接对应的指令,分别是Cgt.Clt.Ceq.大于等于.小于等于.不等于没有直接对应的指令,它的运算实现一般是取反. 大于.小于.等于需要两个参数,它们的通用步骤1.生成加载左边变量2.生成加载右边变量3.生成比较运算指令 生成等于比较的代码实例: ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilG…
C#支持的位运算是与.或.异或.取反.左移.右移,它们对应的指令是And.Or.Xor.Not.Shl.Shr. 取反运算只需要一个操作数,生成步骤是1.生成加载变量2.生成取反指令实例代码: ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Not); 其它五个运算都需要两个参数,它们的通用步骤1.生成加载左边变量2.生成加载右边变量3.生成运算指令 实例: ilGenerator.Emit(OpCodes.Ldarg_0)…
MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item"和"set_Item". 下面我们来生成如下的带有索引器的类 using System; namespace LX1_ILDemo { public class IndexerDemo { private string[,] _CustomerNames; public string th…
MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest { public static void RunAction(Action act) { act(); } public static void TestRunAction() { Action act = () => { Console.WriteLine("Test Action"…
这一篇讲解方法内的局部变量是怎么声明.怎样保存.怎样加载的. 声明局部变量声明用ILGenerator的DeclareLocal方法,参数是局部变量的数据类型,得到一个局部变量对应的创建类LocalBuilder.使用格式是LocalBuilder localBuilderx = ilGenerator.DeclareLocal(typeof(<数据类型>));实际例子 LocalBuilder localBuilderv1 = ilGenerator.DeclareLocal(typeof(…
逻辑运算有三种:与.或.非.实现它们可以用位运算指令And.Or.Not等三个指令.它们的使用方法和位运算一致. 完整的程序如下: using System; using System.Reflection; using System.Reflection.Emit; namespace LX1_ILDemo { class Demo18_BoolOP { static string binaryName = "Demo18_BoolOP.exe"; static string nam…
这一篇讲的是怎样加载整数值到运算栈上.这一类的指令都是以Ldc_I4开头. Ldc_I4类OpCodes的Ldc_I4字段的功能是把一个int值压入运算栈上.它的使用方法是ilGenerator.Emit(OpCodes.Ldc_I4, <整数值>);产生的指令是ldc.i4 <整数值>几个例子 ilGenerator.Emit(OpCodes.Ldc_I4, 2000);//ldc.i4 2000 ilGenerator.Emit(OpCodes.Ldc_I4, -100);//…
我们学习编程开始时,一般用输出"hello world"的一段程序. C#版的"hello world"是 using System; namespace L01_HelloDemo { class HelloWorld { class Hello { public static void Main2() { Console.WriteLine("Hello World!"); Console.ReadKey(); } } } } 用生成IL方式…
本篇讲述怎么加载null.string值.long值.float值.double值. 加载null不需要参数值,只要 Emit ldnull 其它几个命令要 Emit <指令> <值> 加载null 加载null是很简单的,使用OpCodes.Ldnull,以下一句程序就可以了. ilGenerator.Emit(OpCodes.Ldnull); 加载string值 加载string值也很简单,使用OpCodes.Ldstr,格式是 ilGenerator.Emit(OpCodes…
这一篇讲解怎么加载bool值.sbyte值.byte值.char值.short值. 加载bool值在.NET程序实际运行中,是没有true和false值的,实际上是以1和0表示它们,加载它们的指令是Ldc_I4_1和Ldc_I4_0.下面是实际例子:/* 加载true,即加载1 */ilGenerator.Emit(OpCodes.Ldc_I4_1);/* 加载false,即加载0 */ilGenerator.Emit(OpCodes.Ldc_I4_0); 加载sbyte值sbyte是8位有符号…
本篇讲解怎么创建字段,主要是在修饰符的创建上. 创建字段的方法是TypeBuilder.DefineField,传入字段名称.字段类型.字段修饰符等参数,返回一个FieldBuilder对象.先看这一句程序 FieldBuilder nameFieldBuilder = typeBuilder.DefineField("Name", typeof(string), FieldAttributes.Private); 上面一条程序是创建一个叫"Name"的数据类型为&…
创建枚举类型比较简单,主要使用moduleBuilder.DefineEnum 和enumBuilder.DefineLiteral. 第一步:创建 EnumBuilder 创建 EnumBuilder用moduleBuilder.DefineEnum方法,参数是(<枚举类型名称>,<访问控制符>,<类型>)具体例子是这样 EnumBuilder enumBuilder = moduleBuilder.DefineEnum(namespaceName + ".…
本篇讲解实现创建方法.指定参数的名称.实现参数加out和ref修饰符.以及参数加默认值. 创建方法 创建方法用类TypeAttributes的 DefineMethod(string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes) 方法,返回结果是MethodBuilder,就可以创普通方法. 例子 MethodBuilder m2 = typeBuilder.DefineMethod("M2&…
字段有静态字段和非静态字段之分,它们的加载保存指令也是不一样的,并且非静态字段要生成this. 静态字段的加载加载静态字段的指令是Ldsfld.ilGenerator.Emit(OpCodes.Ldsfld, <FieldBuilder>);实际例子 ilGenerator.Emit(OpCodes.Ldsfld, areaFieldBuilder); ilGenerator.Emit(OpCodes.Call, writeStringLineMethod); 静态字段的保存保存静态字段的指令…
本篇讲解怎么生成属性,包括get和set方法. 第一步,生成一个字段生成字段用TypeBuilder.DefineField方法.实例代码: FieldBuilder customerNameBldr = typeBuilder.DefineField ("_CustomerName",typeof(string),FieldAttributes.Private); 第二步,创建一个PropertyBuilder对象创建PropertyBuilder对象需要用生成字段用方法TypeBu…
本篇讲解生成构造函数的一些知识,包括创建实例构造函数.静态构造函数.调用父类构造函数. 生成构造函数的方法生成构造函数的方法是TypeBuilder.DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes),调用它返回一个ConstructorBuilder对象. 实例: ConstructorBuilder newBuilder = ty…
本篇讲述怎样装箱拆箱.装箱和拆箱都是针对值类型而言的,装箱的性能开销远比拆箱的性能开销大. 装箱装箱指令是Box.使用格式是 ILGenerator.Emit(OpCodes.Box,<值类型>); 装箱当然是对一个值类型装箱的,所以第二个参数一定是int,float等一类的值类型.实例: ilGenerator.Emit(OpCodes.Box,typeof(int)); 拆箱 拆箱指令是OpCodes.Unbox_Any和OpCodes.Unbox.他们的区别是Unbox指令不包含伴随着拆…
本篇讲解怎么生成和操作一维数组.各种数组类型创建的步骤是一样的,但是加载和保存步骤有所不同. 一.创建数组所有类型的一维数组创建都是一样的,分三步.1.加载数组长度2.生成指令 Newarr <数组成员类型>3.保存 实例代码: ilGenerator.Emit(OpCodes.Ldc_I4_S, (); ilGenerator.Emit(OpCodes.Newarr, typeof(int)); ilGenerator.Emit(OpCodes.Stloc_0); 二.数组的成员保存这里的数…
本篇讲解怎么样生成接口,即interface. 一.创建类型创建一个接口类型依旧用ModuleBuilder的DefineType方法,但是它的第二个参数必须要有TypeAttributes.Interface | TypeAttributes.Abstract.这样才能是一个接口类型. 实例代码: TypeBuilder typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttribu…
if...else...语句是非常重要的选择语句,它的生成一般需要ILGenerator的DefineLabel方法和MarkLabel方法,以及Brtrue_S和Br_S指令. 一.DefineLabel方法简单调用ILGenerator的DefineLabel方法会得到一个Label结构体.Label结构体没有复杂的功能,只是简单做一个标签.实例代码: Label label1 = ilGenerator.DefineLabel(); 二.MarkLabel方法MarkLabel方法的参数只…
闭包(Closure)是词法闭包(Lexical Closure)的简称.对闭包的具体定义有很多种说法,这些说法大体可以分为两类: 一种说法认为闭包是符合一定条件的函数,比如参考资源中这样定义闭包:闭包是在其词法上下文中引用了自由变量(注1)的函数.另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体.比如参考资源中就有这样的的定义:在实现深约束(注2)时,需要创建一个能显式表示引用环境的东西,并将它与相关的子程序捆绑在一起,这样捆绑起来的整体被称为闭包.这两种定义在某种意义上是对立的,…
一.类的强制转换1.转换成某个类用Castclass指令.实例代码:ilGenerator.Emit( OpCodes.Castclass , typeof(ClassA) ); 2.转换成某个值类型用Unbox_Any指令.实例代码:ilGenerator.Emit( OpCodes.Unbox_Any , typeof(DateTime) );ilGenerator.Emit( OpCodes.Unbox_Any , typeof(int) ); 二.值类型的强制转换 1.转化为sbyte用…
一.创建class用MethodBuilder的DefineType方法,可以指定父类,得到一个TypeBuilder对象. 二.实现继承接口用TypeBuilder的AddInterfaceImplementation方法. 三.显示方法重写用TypeBuilder的DefineMethodOverride方法. 完整代码如下: using System; using System.Reflection; using System.Reflection.Emit; namespace LX1_…
方法调用指令主要有Call和Callvirt. 调用static或sealed修饰的方法,用Call指令. 调用virtual或abstract修饰的方法,用Callvirt指令. 代码实例: ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int)}));…
struct(结构)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体.所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈(stack)上,它本身存储了值,而不包含指向该值的指针. 一.声明struct和声明class一样,用ModuleBuilder的DefineType方法,但是要求第二个参数是TypeAttributes.Sealed,第三个参数是typeof(ValueType).实例:var typeBuild…
生成内部类用TypeBuilder的DefineNestedType方法,得到另一个TypeBuilder.内部类的可访问性都是TypeAttributes的“Nested”开头一些成员.实例代码:ypeBuilder nestedBuilder = typeBuilder.DefineNestedType("NestedClass", TypeAttributes.NestedPublic | TypeAttributes.Sealed); 完整程序如下: using System;…
foreach可以迭代数组或者一个集合对象.foreach语句格式是它的生成步骤是foreach (<成员> in <集合>) <循环体> 一.声明三个变量,local0调用get_Current结果,local1保存集合对象的调用GetEnumerator结果,local2调用MoveNext结果.二.声明四个标签,分别是循环开始标签.finally结束标签.MoveNext标签.get_Current标签三.调用集合对象的GetEnumerator方法,保存结果到相…
break和continue本质都是标签的跳转…
for语句格式是这样的for(<初始化语句>;<条件语句>;<自增减语句>) <循环体> 它可以转换为while语句 if(<条件语句>){ <初始化语句> while(<条件语句>) { <循环体> <自增减语句> }} 那么就可以按照这while语句生成.…