MSIL实用指南-一维数组的操作
本篇讲解怎么生成和操作一维数组。各种数组类型创建的步骤是一样的,但是加载和保存步骤有所不同。
一.创建数组
所有类型的一维数组创建都是一样的,分三步。
1.加载数组长度
2.生成指令 Newarr <数组成员类型>
3.保存
实例代码:
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(int));
ilGenerator.Emit(OpCodes.Stloc_0);
二.数组的成员保存
这里的数组类型是byte、short、int、long、float、double和其它。它们的保存到成员的步骤是相似的。
首先以int型为例,它有四步。
1.加载数组变量
2.加载索引号
3.加载值
4.生成Stelem_I4指令
实例程序:
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldc_I4, int.MaxValue);
ilGenerator.Emit(OpCodes.Stelem_I4);
其它几种类型的前三步和int类型是一样的,只有最后一步不同,它们各有各的指令,对应关系是
byte:Stelem_I1
short:Stelem_I2
int:Stelem_I4
long:Stelem_I8
float:Stelem_R4
double:Stelem_R8
其它:Stelem_Ref
三.其它类型的成员加载
加载也和保存类似。首先以int型数组为例,要分三步
1.加载数组变量
2.加载索引号
3.生成Ldelem_I4指令
实例程序:
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_I4);
其它类型的第三步指令各不相同,对应关系是
byte:Ldelem_I1
short:Ldelem_I2
int:Ldelem_I4
long:Ldelem_I8
float:Ldelem_R4
double:Ldelem_R8
其它:Ldelem_Ref
完整的程序如下
using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
public class Demo21_ArrayOne
{
static string binaryName = "Demo21_ArrayOne.dll";
static string namespaceName = "LX1_ILDemo";
static string typeName = "DemoArrayOne"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder;
static MethodBuilder methodBuilder;
static ILGenerator ilGenerator;
public static void Generate()
{
InitAssembly();
typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public | TypeAttributes.Abstract); methodBuilder = typeBuilder.DefineMethod("TestArray",
MethodAttributes.Public | MethodAttributes.Static,
typeof(void), new Type[] { });
ilGenerator = methodBuilder.GetILGenerator(); LocalBuilder localBuilderv1 = ilGenerator.DeclareLocal(typeof(int[]));
LocalBuilder localBuilderv2 = ilGenerator.DeclareLocal(typeof(int));
LocalBuilder localBuilderv3 = ilGenerator.DeclareLocal(typeof(float[]));
LocalBuilder localBuilderv4 = ilGenerator.DeclareLocal(typeof(float));
LocalBuilder localBuilderv5 = ilGenerator.DeclareLocal(typeof(string[]));
LocalBuilder localBuilderv6 = ilGenerator.DeclareLocal(typeof(string)); ilGenerator.Emit(OpCodes.Nop);
Generate_IntArray();
Generate_FloatArray();
Generate_StringArray(); ilGenerator.Emit(OpCodes.Ret);
SaveAssembly();
Console.WriteLine("生成成功");
} static void Generate_IntArray()
{
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(int));
ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldc_I4, int.MaxValue);
ilGenerator.Emit(OpCodes.Stelem_I4); ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_I4);
ilGenerator.Emit(OpCodes.Stloc_1);
} static void Generate_FloatArray()
{
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(float));
ilGenerator.Emit(OpCodes.Stloc_2); ilGenerator.Emit(OpCodes.Ldloc_2);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldc_I4, float.MaxValue);
ilGenerator.Emit(OpCodes.Stelem_R4); ilGenerator.Emit(OpCodes.Ldloc_2);
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_R4);
ilGenerator.Emit(OpCodes.Stloc_3);
} static void Generate_StringArray()
{
ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte));
ilGenerator.Emit(OpCodes.Newarr, typeof(string));
ilGenerator.Emit(OpCodes.Stloc_S, (sbyte)); ilGenerator.Emit(OpCodes.Ldloc_S, (sbyte));
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldstr,"test string");
ilGenerator.Emit(OpCodes.Stelem_Ref); ilGenerator.Emit(OpCodes.Ldloc_S, (sbyte));
ilGenerator.Emit(OpCodes.Ldc_I4_0);
ilGenerator.Emit(OpCodes.Ldelem_Ref);
ilGenerator.Emit(OpCodes.Stloc_S, (sbyte));
} 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实用指南-一维数组的操作的更多相关文章
- MSIL实用指南-生成索引器
MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...
- MSIL实用指南-Action的生成和调用
MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest ...
- MSIL实用指南-struct的生成和操作
struct(结构)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体.所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈( ...
- MSIL实用指南-装箱拆箱
本篇讲述怎样装箱拆箱.装箱和拆箱都是针对值类型而言的,装箱的性能开销远比拆箱的性能开销大. 装箱装箱指令是Box.使用格式是 ILGenerator.Emit(OpCodes.Box,<值类型& ...
- MSIL实用指南-生成foreach语句
foreach可以迭代数组或者一个集合对象.foreach语句格式是它的生成步骤是foreach (<成员> in <集合>) <循环体> 一.声明三个变量,loc ...
- MSIL实用指南-给字段、属性、方法、类、程序集加Attribute
C#编程中可以给字段.方法.类以及程序集加特性即继承于Attribute的类.这里讲解怎么在IL中给它们加上特性. 生成字段的对应的类是FieldBuilder,生成属性的对应的类是PropertyB ...
- MSIL实用指南-创建对象
创建对象用Newobj指令,它的操作是创建一个新的对象或值类型,并将对象引用的新实例到计算堆栈上.格式是Newobj <构造函数>实例: ilGenerator.Emit(OpCodes. ...
- MSIL实用指南-IL版hello world
我们学习编程开始时,一般用输出"hello world"的一段程序. C#版的"hello world"是 using System; namespace L0 ...
- MSIL实用指南-加载null、string、long、float、double等值
本篇讲述怎么加载null.string值.long值.float值.double值. 加载null不需要参数值,只要 Emit ldnull 其它几个命令要 Emit <指令> <值 ...
随机推荐
- hbase 导入导出、hbase shell 基本命令。
数据导入 ./hbase org.apache.hadoop.hbase.mapreduce.Driver import 表名 数据文件位置hdfs数据文件位置 可以加 前缀 file:/// ...
- setTimeout模拟interval
/** * @param fn: {Function} // function which to execute * @param timer: {number} // gap time betwee ...
- 2018 年 3 月 iOS架构师 面试总结
序言: 今年2月中下旬因为个人原因,换了一份工作,3月初期间面试了有3,4家,基本都是D轮或者刚刚上市的公司,也有上榜的BAT,也从他们的面试笔试中看到了自己的一些不足,于是就想写出来和大家分享一下, ...
- Scala编程快速入门系列(二)
目 录 一.Scala概述 二.Scala数据类型 三.Scala函数 四.Scala集合 五.Scala伴生对象 六.Scala trait 七.Actor 八.隐式转换与隐式参数 九.Sca ...
- Java中String字符串常量池总结
最近到广州某建站互联网公司面试,当时面试官问假设有两个字符串String a="abc",String b = "abc";问输出a==b是true还是fals ...
- 利用CVE-2017-11882拿到持久性shell
利用CVE-2017-11882拿到持久性shell 近日微软又爆出一个严重漏洞,利用该漏洞可以直接拿到目标机shell.这么好玩的东西怎么能错过了,于是搭建环境复现了一把. 首先去GitHub上下载 ...
- npm5 packag-lock.json
前几天升级了 Node.js v8.0 后,自带的 npm 也升级到了5.0,第一次使用的时候确实惊艳到了:原本重新安装一次模块要十几秒到事情,现在一秒多就搞定了.先不要激动,现在我来大概讲一下 np ...
- JDK1.8源码(四)——java.util.Arrays 类
java.util.Arrays 类是 JDK 提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名Arrays调用. 1.asList public static ...
- Omron 论坛软件下载连接
全部软件目录 (更新时间:2017年1月5日) 序号 产品类别 软件名称 1 FA自动化设备 RFID系统 V600-CA5DUSB驱动程序 2 FA自动化设备 可编程控制器 CJ2/CP1USB驱动 ...
- Linux快速搭建FTP服务器
FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(A ...