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;
using System.Reflection.Emit; namespace LX1_ILDemo
{
class Demo16_NumberOP
{
static string binaryName = "Demo16_NumberOP.exe";
static string namespaceName = "LX1_ILDemo";
static string typeName = "NumberOPDemo"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder;
static MethodBuilder mainMethod;
static MethodBuilder testMethod; static void Emit_Test()
{
testMethod = typeBuilder.DefineMethod("TestOP", MethodAttributes.Public
| MethodAttributes.Static, typeof(void), new Type[] {typeof(double), typeof(double)});
var println= typeof(Console).GetMethod("WriteLine", new Type[] { typeof(double) });
var ilGenerator = testMethod.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Add);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Sub);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Mul);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Div);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Rem);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ret);
} public static void Generate()
{
InitAssembly();
typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public);
Emit_Test();
GenerateMain();
assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);
SaveAssembly();
Console.WriteLine("生成成功");
} static void GenerateMain()
{
mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public
| MethodAttributes.Static, typeof(void), new Type[] { });
var ilGenerator = mainMethod.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldc_R8,(double));
ilGenerator.Emit(OpCodes.Ldc_R8, (double));
ilGenerator.Emit(OpCodes.Call, testMethod); ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadKey", new Type[] { }));
ilGenerator.Emit(OpCodes.Pop);
ilGenerator.Emit(OpCodes.Ret);
} 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实用指南-比较运算
数值的比较就是大于.小于.等于.大于等于.小于等于.不等于,它们的运算结果都是布尔值.大于.小于.等于有直接对应的指令,分别是Cgt.Clt.Ceq.大于等于.小于等于.不等于没有直接对应的指令,它的 ...
- MSIL实用指南-位运算
C#支持的位运算是与.或.异或.取反.左移.右移,它们对应的指令是And.Or.Xor.Not.Shl.Shr. 取反运算只需要一个操作数,生成步骤是1.生成加载变量2.生成取反指令实例代码: ilG ...
- MSIL实用指南-生成索引器
MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...
- MSIL实用指南-Action的生成和调用
MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest ...
- MSIL实用指南-局部变量的声明、保存和加载
这一篇讲解方法内的局部变量是怎么声明.怎样保存.怎样加载的. 声明局部变量声明用ILGenerator的DeclareLocal方法,参数是局部变量的数据类型,得到一个局部变量对应的创建类LocalB ...
- MSIL实用指南-逻辑运算
逻辑运算有三种:与.或.非.实现它们可以用位运算指令And.Or.Not等三个指令.它们的使用方法和位运算一致. 完整的程序如下: using System; using System.Reflect ...
- MSIL实用指南-加载int值
这一篇讲的是怎样加载整数值到运算栈上.这一类的指令都是以Ldc_I4开头. Ldc_I4类OpCodes的Ldc_I4字段的功能是把一个int值压入运算栈上.它的使用方法是ilGenerator.Em ...
- 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 <指令> <值 ...
随机推荐
- SpringBoot2.1.6 + Shiro1.4.1 + Thymeleaf + Jpa整合练习
首先,添加maven依赖,完整的pom文件如下: <?xml version="1.0" encoding="UTF-8"?> <projec ...
- JavaOOP 对象和封装
1.后缀:jsp---相当于html,但是它里面可以写java代码. 2.包名取名规则 a.网站域名倒着写 b.字母小写 3.类名取名规则 a.首字母大写 4.三目运算(适用简单的if-else) 条 ...
- 树状数组(binary index tree)
概述 修改和查询复杂度为log(n)的数据结构,所有奇数位的数和原数位置相同,偶数位置是原数组若干位置的和. 假如原数组A(a1, a2, a3, a4 ...),和其对应的树状数组C(c1, c2, ...
- some (1)
每次在写博客的时候,都是自己觉得在工作中非常重要的东西,写东西的时候,也是一个思考的过程.好的东西不光帮助别人,也使自己有进一步的理解.
- hibernate 命名策略
对于Java开发人员,Hibernate 3 annotations提供了非常好的方式来展示域分层.你可以很轻松的通过Hibernate自动生成需要的数据库架构,带有完整的SQL脚本.然而回到现实世界 ...
- 使用Minifly打造基于视觉感知的跟踪无人机
前言:无人机和人工智能现在是非常热门的话题,将两者结合起来是一个比较好的创意,本文介绍一种可行的解决方案来实现基于视觉感知的跟踪无人机.从零开始搭建无人机系统工作量和难度(以及钱)都是非常大的,所以在 ...
- 浅谈Ceph纠删码
目 录第1章 引言 1.1 文档说明 1.2 参考文档 第2章 纠删码概念和原理 2.1 概念 2.2 原理 第3章 CEPH纠删码介绍 3.1 CEPH纠删码用途 3.2 CEPH纠删码库 3.3 ...
- DataPipeline丨DataOps理念与设计原则
作者:DataPipeline CEO 陈诚 上周我们探讨了数据的「资产负债表」与「现状」,期间抛给大家一个问题:如果我们制作一个企业的“数据资产负债表”,到底会有多少数据是企业真正的资产? 数据出现 ...
- 6、高级的数组的复制(test4.java)
这里指的高级,并不是过么高大上,而是说我们可以调用系统函数,直接对数组进行复制,并且这个函数的强大并不止局限于,对数组的复制,而且可以对数组进行截取,在指定位置插入或删除某个元素. 本篇只介绍数组的复 ...
- 使用ADO.NET操作SqlServer,开启一个事务
1.创建SqlConnection对象(connStr是链接字符串) SqlConnection conn = new SqlConnection(connStr); 2.创建SqlTransacti ...