这一篇讲的是怎样加载整数值到运算栈上。这一类的指令都是以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);//ldc.i4 -100
ilGenerator.Emit(OpCodes.Ldc_I4, -1);//ldc.i4 -1

Ldc_I4_S
类OpCodes的Ldc_I4_S字段的功能是把一个将从-128 到 127 之间的整数值压入运算栈上。如果整数值小于0,则必须强制转换为sbyte。它的使用方法是
ilGenerator.Emit(OpCodes.Ldc_I4_S <整数值>);
产生的指令是ldc.i4 <整数值>
几个例子

ilGenerator.Emit(OpCodes.Ldc_I4_S, (SByte)(-1));//ldc.i4.s -1
ilGenerator.Emit(OpCodes.Ldc_I4_S, 127);//ldc.i4.s 127
ilGenerator.Emit(OpCodes.Ldc_I4_S, 0);//ldc.i4.s 0

Ldc_I4_M1、Ldc_I4_0、Ldc_I4_1、Ldc_I4_2、Ldc_I4_3、Ldc_I4_4、Ldc_I4_5、Ldc_I4_6、Ldc_I4_7、Ldc_I4_8
Ldc_I4_M1作用是将-1推送到计算堆栈上,Ldc_I4_0作用是将0推送到计算堆栈上,Ldc_I4_1作用是将1推送到计算堆栈上,Ldc_I4_2作用是将2推送到计算堆栈上,Ldc_I4_3作用是将3推送到计算堆栈上,Ldc_I4_4作用是将4推送到计算堆栈上,Ldc_I4_5作用是将5推送到计算堆栈上,Ldc_I4_6作用是将6推送到计算堆栈上,Ldc_I4_7作用是将7推送到计算堆栈上,Ldc_I4_8作用是将8推送到计算堆栈上。

它们的使用方法是

ilGenerator.Emit(OpCodes.Ldc_I4_M1);//ldc.i4.m1
ilGenerator.Emit(OpCodes.Ldc_I4_0);//ldc.i4.0
ilGenerator.Emit(OpCodes.Ldc_I4_1);//ldc.i4.1
ilGenerator.Emit(OpCodes.Ldc_I4_2);//ldc.i4.2
ilGenerator.Emit(OpCodes.Ldc_I4_3);//ldc.i4.3
ilGenerator.Emit(OpCodes.Ldc_I4_4);//ldc.i4.4
ilGenerator.Emit(OpCodes.Ldc_I4_5);//ldc.i4.5
ilGenerator.Emit(OpCodes.Ldc_I4_6);//ldc.i4.6
ilGenerator.Emit(OpCodes.Ldc_I4_7);//ldc.i4.7
ilGenerator.Emit(OpCodes.Ldc_I4_8);//ldc.i4.8

ilGenerator.Emit(OpCodes.Ldc_I4_M1)和ilGenerator.Emit(OpCodes.Ldc_I4, -1)、ilGenerator.Emit(OpCodes.Ldc_I4_S, (SByte)(-1))运行的结果是一条的,但是效率更高;同样的ilGenerator.Emit(OpCodes.Ldc_I4_0)和ilGenerator.Emit(OpCodes.Ldc_I4, 0)、ilGenerator.Emit(OpCodes.Ldc_I4_S, 0)运行结果一样,效率更高,等等。
在-128 到 127 之间的整数值用Ldc_I4_S比Ldc_I4更好。
所以可以把加载整数值用一个方法代替

        public static void LoadInt(ILGenerator il, int value)
{
switch (value)
{
case -1:
il.Emit(OpCodes.Ldc_I4_M1);
return;
case 0:
il.Emit(OpCodes.Ldc_I4_0);
return;
case 1:
il.Emit(OpCodes.Ldc_I4_1);
return;
case 2:
il.Emit(OpCodes.Ldc_I4_2);
return;
case 3:
il.Emit(OpCodes.Ldc_I4_3);
return;
case 4:
il.Emit(OpCodes.Ldc_I4_4);
return;
case 5:
il.Emit(OpCodes.Ldc_I4_5);
return;
case 6:
il.Emit(OpCodes.Ldc_I4_6);
return;
case 7:
il.Emit(OpCodes.Ldc_I4_7);
return;
case 8:
il.Emit(OpCodes.Ldc_I4_8);
return;
} if (value > -129 && value < 128)
{
il.Emit(OpCodes.Ldc_I4_S, (SByte)value);
}
else
{
il.Emit(OpCodes.Ldc_I4, value);
}
}

  

完整的程序如下

using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
class Demo1_LoadIntIL
{
static string binaryName = "LoadIntDemo.exe";
static string namespaceName = "LX1_ILDemo";
static string typeName = "LoadInt"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder;
static MethodBuilder mainMethod;
static ILGenerator ilGenerator;
static MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }); public static void LoadInt(ILGenerator il, int value)
{
switch (value)
{
case -:
il.Emit(OpCodes.Ldc_I4_M1);
return;
case :
il.Emit(OpCodes.Ldc_I4_0);
return;
case :
il.Emit(OpCodes.Ldc_I4_1);
return;
case :
il.Emit(OpCodes.Ldc_I4_2);
return;
case :
il.Emit(OpCodes.Ldc_I4_3);
return;
case :
il.Emit(OpCodes.Ldc_I4_4);
return;
case :
il.Emit(OpCodes.Ldc_I4_5);
return;
case :
il.Emit(OpCodes.Ldc_I4_6);
return;
case :
il.Emit(OpCodes.Ldc_I4_7);
return;
case :
il.Emit(OpCodes.Ldc_I4_8);
return;
} if (value > - && value < )
{
il.Emit(OpCodes.Ldc_I4_S, (SByte)value);
}
else
{
il.Emit(OpCodes.Ldc_I4, value);
}
} /// <summary>
/// Ldc_I4_*类指令生成
/// </summary>
static void Emit_Ldc_I4_X()
{
/* 生成 Console.WriteLine(-1); */
ilGenerator.Emit(OpCodes.Ldc_I4_M1);//ldc.i4.m1
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(0); */
ilGenerator.Emit(OpCodes.Ldc_I4_0);//ldc.i4.0
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(1); */
ilGenerator.Emit(OpCodes.Ldc_I4_1);//ldc.i4.1
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(2); */
ilGenerator.Emit(OpCodes.Ldc_I4_2);//ldc.i4.2
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(3); */
ilGenerator.Emit(OpCodes.Ldc_I4_3);//ldc.i4.3
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(4); */
ilGenerator.Emit(OpCodes.Ldc_I4_4);//ldc.i4.4
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(5); */
ilGenerator.Emit(OpCodes.Ldc_I4_5);//ldc.i4.5
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(6); */
ilGenerator.Emit(OpCodes.Ldc_I4_6);//ldc.i4.6
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(7); */
ilGenerator.Emit(OpCodes.Ldc_I4_7);//ldc.i4.7
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(8); */
ilGenerator.Emit(OpCodes.Ldc_I4_8);//ldc.i4.8
ilGenerator.Emit(OpCodes.Call, writeLineMethod);
} static void Emit_Ldc_I4_S()
{
/* 生成 Console.WriteLine(-1); */
ilGenerator.Emit(OpCodes.Ldc_I4_S, (SByte)(-));//ldc.i4.s -1
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(0); */
ilGenerator.Emit(OpCodes.Ldc_I4_S, );//ldc.i4.s 0
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(8); */
ilGenerator.Emit(OpCodes.Ldc_I4_S, );//ldc.i4.s 8
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(100); */
ilGenerator.Emit(OpCodes.Ldc_I4_S, );//ldc.i4.s 100
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(127); */
ilGenerator.Emit(OpCodes.Ldc_I4_S, );//ldc.i4.s 127
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(-128); */
ilGenerator.Emit(OpCodes.Ldc_I4_S, (SByte) (- ));//ldc.i4.s -128
ilGenerator.Emit(OpCodes.Call, writeLineMethod);
} static void Emit_Ldc_I4()
{
/* 生成 Console.WriteLine(-1); */
ilGenerator.Emit(OpCodes.Ldc_I4, -);//ldc.i4 -1
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(0); */
ilGenerator.Emit(OpCodes.Ldc_I4, );//ldc.i4 0
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(8); */
ilGenerator.Emit(OpCodes.Ldc_I4, );//ldc.i4 8
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(-100); */
ilGenerator.Emit(OpCodes.Ldc_I4, -);//ldc.i4 -100
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(127); */
ilGenerator.Emit(OpCodes.Ldc_I4, );//ldc.i4 127
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(-128); */
ilGenerator.Emit(OpCodes.Ldc_I4, (-));//ldc.i4 -128
ilGenerator.Emit(OpCodes.Call, writeLineMethod); /* 生成 Console.WriteLine(2000); */
ilGenerator.Emit(OpCodes.Ldc_I4, );//ldc.i4 2000
ilGenerator.Emit(OpCodes.Call, writeLineMethod);
} public static void Generate()
{
InitAssembly(); /* 生成 public class LoadInt */
typeBuilder = moduleBuilder.DefineType( namespaceName+"."+ typeName, TypeAttributes.Public); /* 生成 public static void Main() */
GenerateMain(); Emit_Ldc_I4_X();
Emit_Ldc_I4_S();
Emit_Ldc_I4(); EmitReadKey();
ilGenerator.Emit(OpCodes.Ret); /* 设置assembly入口方法 */
assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication); SaveAssembly();
Console.WriteLine("生成成功");
//Console.ReadKey();
} static void EmitReadKey()
{
/* 生成 Console.ReadKey(); */
MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
ilGenerator.Emit(OpCodes.Call, readKeyMethod);
ilGenerator.Emit(OpCodes.Pop);
} static void GenerateMain()
{
mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] { });
ilGenerator = mainMethod.GetILGenerator();
} static void InitAssembly()
{
AssemblyName assemblyName = new AssemblyName(namespaceName);
assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, binaryName);
} static void SaveAssembly()
{
Type t = typeBuilder.CreateType(); //完成Type,这是必须的
assemblyBuilder.Save(binaryName);
}
}
}

MSIL实用指南-加载int值的更多相关文章

  1. MSIL实用指南-加载bool、sbyte、byte、char、short等值

    这一篇讲解怎么加载bool值.sbyte值.byte值.char值.short值. 加载bool值在.NET程序实际运行中,是没有true和false值的,实际上是以1和0表示它们,加载它们的指令是L ...

  2. MSIL实用指南-加载null、string、long、float、double等值

    本篇讲述怎么加载null.string值.long值.float值.double值. 加载null不需要参数值,只要 Emit ldnull 其它几个命令要 Emit <指令> <值 ...

  3. MSIL实用指南-加载和保存参数

    本篇讲解怎么加载和保存参数,以及参数起始序号的确定. 参数的加载加载参数的指令是Ldarg.Ldarg_S.Ldarg_0.Ldarg_1.Ldarg_2.Ldarg_3.Ldarg_0是加载第0个参 ...

  4. MSIL实用指南-Action的生成和调用

    MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest ...

  5. MSIL实用指南-生成索引器

    MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...

  6. MSIL实用指南-字段的加载和保存

    字段有静态字段和非静态字段之分,它们的加载保存指令也是不一样的,并且非静态字段要生成this. 静态字段的加载加载静态字段的指令是Ldsfld.ilGenerator.Emit(OpCodes.Lds ...

  7. MSIL实用指南-局部变量的声明、保存和加载

    这一篇讲解方法内的局部变量是怎么声明.怎样保存.怎样加载的. 声明局部变量声明用ILGenerator的DeclareLocal方法,参数是局部变量的数据类型,得到一个局部变量对应的创建类LocalB ...

  8. MSIL实用指南-一维数组的操作

    本篇讲解怎么生成和操作一维数组.各种数组类型创建的步骤是一样的,但是加载和保存步骤有所不同. 一.创建数组所有类型的一维数组创建都是一样的,分三步.1.加载数组长度2.生成指令 Newarr < ...

  9. MSIL实用指南-比较运算

    数值的比较就是大于.小于.等于.大于等于.小于等于.不等于,它们的运算结果都是布尔值.大于.小于.等于有直接对应的指令,分别是Cgt.Clt.Ceq.大于等于.小于等于.不等于没有直接对应的指令,它的 ...

随机推荐

  1. 关于Spring的JDBC连接mysql(与传统jdbc比较)

    Spring的jdbc与Hibernate,Mybatis相比较,功能不是特别强大,但是在小型项目中,也到还是比较灵活简单. 首先可以看看一下传统的jdbc是如何操作的呢 传统JDBC 首先呢先要创建 ...

  2. python下载报错:Could not install packages due to an EnvironmentError: [WinError 5] 拒绝访问

    更新pip模块的版本:python -m pip install --upgrade pip 但是遇到报错提示: Could not install packages due to an Enviro ...

  3. jango简介

    Django简介   Django框架简介 MVC框架和MTV框架 MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Mode ...

  4. Android的步骤

    1.开发Activity步骤 第一步:写一个类继承Activity 第二步:重写oncreate方法 第三步:在主配置文件中注册activity <activity android:name=& ...

  5. Linux系统管理----账号与权限管理作业习题

    1.创建/guanli 目录,在/guanli下创建zonghe 和 jishu 两个目录(一条命令) 创建目录:mkdir +目录 [root@localhost chen]#mkdir /guan ...

  6. 模块购物商城和ATM机代码:

    http://outofmemory.cn/python/video/let-us-python/ python为程序员服务  快来加入群[python爬虫交流群](群号570070796),发现精彩 ...

  7. Gridea+GitHub搭建个人博客

    某日闲余时间看到一篇介绍Gridea博客平台的文章,大概看了一下觉得此平台还不错,随即自己进入Gridea官网瞅了瞅.哇,这搭建过程也太简单了吧,比Hexo博客搭建要容易很多,而且还有后台管理客户端, ...

  8. Golang版本的rocksdb-对gorocksdb的封装

    rocksdb的优秀特性不用多说,但是它是用c++语言写的,就是这一个特点就把很多人拦住了.虽然rocksdb官方也有Java版本,但是Golang的发展速度让人不容小觑,而且由于golang原生对高 ...

  9. Appium+python自动化(二十七)-让你在手机找到溜冰一样的感觉666,溜得飞起来 - 低级滑动(超详解)

    简介 随着现在智能手机的普及和应用,小到五六岁或者更小的娃娃,老至七八十岁老头老太太都是智能手机的用户,基本上达到每个人都在用,每次在地铁或者公交上,就看看到这样的场面,手指不停地在手机屏幕上来来回回 ...

  10. 后端基于方法的权限控制--Spirng-Security

    后端基于方法的权限控制--Spirng-Security 默认情况下, Spring Security 并不启用方法级的安全管控. 启用方法级的管控后, 可以针对不同的方法通过注解设置不同的访问条件: ...