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 <指令> <值 ...
随机推荐
- NetCore跨平台桌面框架Avalonia的OSX程序打包
虽然工作开发语言已经转到了java,但平时仍会用netcore做一些小工具,提升工作效率,但是笔记本换成了Mac,小工具只能做成命令行形式,很是痛苦,迫切需要一个.net跨平台的桌面程序解决方案. 为 ...
- Pytest进阶之参数化
前言 unittest单元测试框架使用DDT进行数据驱动测试,那么身为功能更加强大且更加灵活的Pytest框架怎么可能没有数据驱动的概念呢?其实Pytest是使用@pytest.mark.parame ...
- 小白学python-day06-
今天是day06,以下是学习内容总结: 但行努力,莫问前程. --------------------------------------------------------------------- ...
- 【Intellij IDEA】设置 jdk 版本
File -> Project Structure... -> Project,如图所示:
- 2019前端面试系列——HTTP、浏览器面试题
浏览器存储的方式有哪些 特性 cookie localStorage sessionStorage indexedDB 数据生命周期 一般由服务器生成,可以设置过期时间 除非被清理,否则一直存在 页面 ...
- 五、Python基础(2)
五,Python基础(2) 1.数据类型基础 (一)什么是数据类型? 用于区分变量值的不同类型. (二)为何对数据分类? 针对不同状态就应该用不同类型的数据去标识. (三)数据类型分类 1.数字类型 ...
- Robotframework获取移动端toast问题
背景: 在做移动端自动化测试的时候,经常会遇到一个问题就是获取toast提示问题,如果需要解决这个问题需要重新处理,不能按照正常的逻辑,使用robotframework自带的关键字进行获取,需要重新考 ...
- 自己动手写Spring框架--IOC、MVC
对于一名Java开发人员,我相信没有人不知道 Spring 框架,而且也能够轻松就说出 Spring 的特性-- IOC.MVC.AOP.ORM(batis). 下面我想简单介绍一下我写的轻量级的 S ...
- 使用阿里云oss
写这篇博文的原因是公司有个项目需要用到阿里云来存放用户头像文件.后期软件安装版本也可能需要存进去,然后折腾了两天终于摸熟了一点皮毛,在这里给大家简单介绍下. 一.初识对象存储oss 1.进入阿里云控制 ...
- 逆向破解之160个CrackMe —— 001
CrackMe —— 001 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...