IL合集
由于之前写的表达式树合集,未编写任何注释且是以图片的形式展现给大家,在这里向各位看官道歉了,接下来为大家奉上新鲜出炉的香喷喷的IL合集,后面会持续更新,各位看官点关注不迷路,之前答应的手写IOC以及多线程合集,目前IOC方面的困难已经解决掉,就差怎么封装了,有想法的看官可以加QQ群6406277,四川观察就是我,多线程方面的后面demo写出来整理好之后,届时会为大家奉上。,IL合集中注释已经写清楚,不明白可以在群里找我,好了,不多啰嗦,正文开始。
首先出场的是两数相加用IL实现
Add
#region Add
{
var methodAdd = typeBulder.DefineMethod("Add", MethodAttributes.Public, typeof(int), new Type[] { typeof(int), typeof(int) });
var ilMethod = methodAdd.GetILGenerator();
var method = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
ilMethod.Emit(OpCodes.Ldarg_1);//取出方法的第一个参数 并加载到栈上
ilMethod.Emit(OpCodes.Ldarg_2);//取出方法的第二个参数 并加载到栈上
ilMethod.Emit(OpCodes.Add);//将第一个和第二个参数相加,
ilMethod.Emit(OpCodes.Stloc_0);//结果赋值给第0个本地变量
ilMethod.Emit(OpCodes.Ldloc_0);//加载倒栈中
ilMethod.EmitCall(OpCodes.Call, method, new Type[] { typeof(int) });//输出
ilMethod.Emit(OpCodes.Ldloc_0);//加载
ilMethod.Emit(OpCodes.Ret);//返回相加后的结果
}
#endregion
And
#region And
{
var methodAnd = typeBulder.DefineMethod("And", MethodAttributes.Public, typeof(int), new Type[] { typeof(int), typeof(int) });
var ilMethod = methodAnd.GetILGenerator();
var method = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
ilMethod.Emit(OpCodes.Ldarg_1);//取出方法的第一个参数 并加载到栈上
ilMethod.Emit(OpCodes.Ldarg_2);//取出方法的第二个参数 并加载到栈上
ilMethod.Emit(OpCodes.And);//将第一个和第二个参数相加,
ilMethod.Emit(OpCodes.Stloc_0);//将And结果 赋值给local
ilMethod.Emit(OpCodes.Ldloc_0);//将Local推到栈
ilMethod.EmitCall(OpCodes.Call, method, new Type[] { typeof(int) });
ilMethod.Emit(OpCodes.Ldloc_0);////将Local推到栈
ilMethod.Emit(OpCodes.Ret);//返回And后的结果
}
#endregion
ble bgt bge等比较大小相关的
#region Beq bgt bge ble blt
{
var method = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
var methodBeq = typeBulder.DefineMethod("Beq",MethodAttributes.Public,typeof(void),new Type[] { typeof(int),typeof(int)});
var ilMethod = methodBeq.GetILGenerator();
var labelEq = ilMethod.DefineLabel();
var labelNotEq= ilMethod.DefineLabel();
ilMethod.Emit(OpCodes.Ldarg_1);//取出方法的第一个参数 并加载到栈上
ilMethod.Emit(OpCodes.Ldarg_2);//取出方法的第二个参数 并加载到栈上
ilMethod.Emit(OpCodes.Beq, labelEq);//第一个和第二个是否相等
ilMethod.Emit(OpCodes.Ldarg_1);//取出方法的第一个参数 并加载到栈上
ilMethod.Emit(OpCodes.Ldarg_2);//取出方法的第二个参数 并加载到栈上
ilMethod.Emit(OpCodes.Bge, labelNotEq);//第一个是否大于等于第二个 可以自行更换为Bgt,ble blt
ilMethod.Emit(OpCodes.Ret);
ilMethod.MarkLabel(labelEq);
ilMethod.Emit(OpCodes.Ldstr, "第一个数等于第二个数");
ilMethod.Emit(OpCodes.Call, method);
ilMethod.Emit(OpCodes.Ret);
ilMethod.MarkLabel(labelNotEq);
ilMethod.Emit(OpCodes.Ldstr, "第一个数大于等于第二个数");
ilMethod.Emit(OpCodes.Call, method);
ilMethod.Emit(OpCodes.Ret);
}
#endregion
IL构造循环代码
#region 循环
{
var method = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
var methodInt = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
var methodXh = typeBulder.DefineMethod("Xunhuan", MethodAttributes.Public, typeof(void), new Type[] { });
var ilMethod = methodXh.GetILGenerator();
var localBegin=ilMethod.DeclareLocal(typeof(int));//定义循环开始变量
var localEnd= ilMethod.DeclareLocal(typeof(int));//结束变量
var labelXunhuan = ilMethod.DefineLabel();//定义循环主体
var labelEnd= ilMethod.DefineLabel();//定义结束标签主体
var labelBreak = ilMethod.DefineLabel();//定义中断标签
ilMethod.Emit(OpCodes.Ldc_I4, 0);//将0加载到栈上
ilMethod.Emit(OpCodes.Stloc_0);//这两句是给第0个局部变量赋值,0
ilMethod.Emit(OpCodes.Ldc_I4, 5);//将5加载到栈上
ilMethod.Emit(OpCodes.Stloc, 1);//这两句是给第1个局部变量赋值,5
ilMethod.Emit(OpCodes.Br, labelXunhuan);//无条件跳转到循环的label,即开始循环
ilMethod.MarkLabel(labelEnd);//标记这段代码是labelend的代码
ilMethod.Emit(OpCodes.Ldstr,"循环结束");
ilMethod.Emit(OpCodes.Call, method);//输出循环结束
ilMethod.Emit(OpCodes.Ret);//返回
ilMethod.MarkLabel(labelBreak);
ilMethod.Emit(OpCodes.Ldstr, "循环终止");
ilMethod.Emit(OpCodes.Call, method);//输出循环结束
ilMethod.Emit(OpCodes.Break);
ilMethod.Emit(OpCodes.Ret);//返回
ilMethod.MarkLabel(labelXunhuan);//标记是labelbegin的代码
ilMethod.Emit(OpCodes.Ldloc_0);//从栈中加载第0个局部变量
ilMethod.Emit(OpCodes.Ldloc_1);//从栈中加载第1个局部变量
ilMethod.Emit(OpCodes.Bge, labelEnd);//比较第0个是否小于等于第一个
ilMethod.Emit(OpCodes.Ldloc_0);//加载循环的第0变量
ilMethod.Emit(OpCodes.Call, methodInt);//打印出来
ilMethod.Emit(OpCodes.Ldc_I4,1);//将1加载到栈上
ilMethod.Emit(OpCodes.Ldloc_0);//从栈中加载第0个局部变量
ilMethod.Emit(OpCodes.Add);//相加
ilMethod.Emit(OpCodes.Stloc, 0);//结果赋值给本地0个局部变量
ilMethod.Emit(OpCodes.Ldc_I4, 3);
ilMethod.Emit(OpCodes.Ldloc_0);//从栈中加载第0个局部变量
ilMethod.Emit(OpCodes.Beq, labelBreak);//比较第0个是否小于等于第一个
ilMethod.Emit(OpCodes.Br, labelXunhuan); } #endregion
IL构建对象
#region NewObj创建对象
{
var conTest = typeof(TestNewobj).GetConstructors().FirstOrDefault(s => s.GetParameters().Length > 0);
DynamicMethod dynamicMethod = new DynamicMethod("CreateInstance", typeof(TestNewobj), new Type[] { typeof(int), typeof(int) });//创建一个动态方法,方法名称,返回值,入参
var il = dynamicMethod.GetILGenerator();
il.Emit(OpCodes.Nop);//不做操作
il.Emit(OpCodes.Ldarg_0);//从堆栈加载出方法的第0索引参数
il.Emit(OpCodes.Ldarg_1);//1索引参数
il.Emit(OpCodes.Newobj,conTest);//调用构造方法,并传入0,1索引参数的值
il.Emit(OpCodes.Ret);//返回创建的对象
var objCreator = dynamicMethod.CreateDelegate(typeof(Func<int,int, TestNewobj>)) as Func<int,int, TestNewobj>;
var result = objCreator(5,10);
var resu = result.Add();
} #endregion
IL实现TryCatch
#region Try Catch
{
var method = typeof(Console).GetMethod("WriteLine",new Type[] { typeof(string)});//输出字符串
var method2 = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });//输出数字
var dynamicMethod = typeBulder.DefineMethod("TryEx",MethodAttributes.Public,CallingConventions.Standard, typeof(string),new Type[] {typeof(object),typeof(object) });//构造方法
var il = dynamicMethod.GetILGenerator();
var local = il.DeclareLocal(typeof(string));//本地string类型变量
var ex = typeof(Exception);
var localEx = il.DeclareLocal(ex);//本地Exception类型变量
var str = ex.GetMethod("ToString");//tostring方法
var exInstance = new Exception();
var localInt = il.DeclareLocal(typeof(int));//本地int变量
il.BeginExceptionBlock();//构造try块
il.Emit(OpCodes.Ldarg_1);//加载第一个变量
il.Emit(OpCodes.Unbox_Any,typeof(int));//加载第一个变量并且将obj转为int
il.Emit(OpCodes.Ldarg_2);//加载第二个变量并且将obj转为int
il.Emit(OpCodes.Unbox_Any, typeof(int));//加载第二个变量并且将obj转为int
il.Emit(OpCodes.Add);//相加
il.Emit(OpCodes.Stloc,2);//赋值给本地第二个int变量
il.Emit(OpCodes.Ldloc, 2);//加载本地第二个int变量
il.Emit(OpCodes.Call, method2);//输出
il.Emit(OpCodes.Ldstr, "正常执行");//加载字符串
il.Emit(OpCodes.Stloc,0);//赋值给第0个变量
il.BeginCatchBlock(ex);//构造catch块
il.Emit(OpCodes.Stloc,1);//将ex赋值给本地exception变量
il.Emit(OpCodes.Ldloc,1);
il.Emit(OpCodes.Callvirt, str);//加载本地ex变量并且tostring一下
il.Emit(OpCodes.Call, method);//输出异常信息
il.Emit(OpCodes.Ldstr, "非正常执行");//加载结果字符串
il.Emit(OpCodes.Stloc, 0);//赋值给第0个变量
il.Emit(OpCodes.Rethrow);//抛出异常 就是throw
il.EndExceptionBlock();//结束catch块
il.Emit(OpCodes.Ldloc,0);//加载第0个字符串变量
il.Emit(OpCodes.Ret);//返回结果
var type = typeBulder.CreateType();
var instance = Activator.CreateInstance(type);
var mh = type.GetMethod("TryEx");
var ttt= mh.Invoke(instance, new object[] { 10,new TestNewobj(1,1)});//此处可以修改为其他类型的变量,testnewobj是我测试用
}
#endregion
好了,今天的分享就结束了,后续会持续更新,欢迎大家关注,
IL合集的更多相关文章
- 【转】Reflector、reflexil、De4Dot、IL相关操作指令合集
PS:CTRL+F 输入你需要的内容,可以快速查找页面上的内容. 名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. ...
- dp合集 广场铺砖问题&&硬木地板
dp合集 广场铺砖问题&&硬木地板 很经典了吧... 前排:思想来自yali朱全民dalao的ppt百度文库免费下载 后排:STO朱全民OTZ 广场铺砖问题 有一个 W 行 H 列的广 ...
- 9.15 DP合集水表
9.15 DP合集水表 显然难了一些啊. 凸多边形的三角剖分 瞄了一眼题解. 和蛤蛤的烦恼一样,裸的区间dp. 设f[i][j]表示i~j的点三角剖分最小代价. 显然\(f[i][i+1]=0,f[i ...
- 9.14 DP合集水表
9.14 DP合集水表 关键子工程 在大型工程的施工前,我们把整个工程划分为若干个子工程,并把这些子工程编号为 1. 2. --. N:这样划分之后,子工程之间就会有一些依赖关系,即一些子工程必须在某 ...
- SQL Server技术内幕笔记合集
SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...
- 【Android】开发中个人遇到和使用过的值得分享的资源合集
Android-Classical-OpenSource Android开发中 个人遇到和使用过的值得分享的资源合集 Trinea的OpenProject 强烈推荐的Android 开源项目分类汇总, ...
- [Erlang 0122] Erlang Resources 2014年1月~6月资讯合集
虽然忙,有些事还是要抽时间做; Erlang Resources 小站 2014年1月~6月资讯合集,方便检索. 小站地址: http://site.douban.com/204209/ ...
- [Erlang 0114] Erlang Resources 小站 2013年7月~12月资讯合集
Erlang Resources 小站 2013年7月~12月资讯合集,方便检索. 附 2013上半年盘点: Erlang Resources 小站 2013年1月~6月资讯合集 小站地 ...
- SQL用法操作合集
SQL用法操作合集 一.表的创建 1.创建表 格式: 1 CREATE TABLE 表名 2 (列名 数据类型(宽度)[DEFAULT 表达式][COLUMN CONSTRAINT], 3 ... ...
随机推荐
- Spring源码解析之ConfigurationClassPostProcessor(三)
在上一章笔者介绍了ConfigurationClassParser.doProcessConfigurationClass(...)方法,在这个方法里调用了processImports(...)方法处 ...
- python入门(需要C++基础)
title: python语法入门 author: Sun-Wind date: August 25, 2021 python语法入门 博主最近参加一项比赛,因为需要用到python,所以在这里记录自 ...
- NVidia Jetson Ubuntu 18.04 安装ROS过程中运行sudo rosdep init指令出错
参考:https://www.cnblogs.com/xuhaoforwards/p/9399744.html 安装ROS过程中运行sudo rosdep init后,出现如下错误LOG: ERROR ...
- 修改anaconda3 jupyter notebook 默认路径
本文参考了: https://blog.csdn.net/u014552678/article/details/62046638 https://blog.csdn.net/qigenhuochai/ ...
- 利用Python快速绘制海报级别地图
1 简介 基于Python中诸如matplotlib等功能丰富.自由度极高的绘图库,我们可以完成各种极富艺术感的可视化作品,关于这一点我在系列文章在模仿中精进数据可视化中已经带大家学习过很多案例了. ...
- MySQL-基础-2
MySQL数据库介绍 • MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理. • MySQL的历 ...
- C++模板简介
模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数.返回值取得任意类型. 模板是一种对类型进行参数化的工具: 通常有两种形式:函 ...
- GIMP 一键均匀添加多条参考线 一键均匀切分图片
添加参考线 #!/usr/bin/env python2 # -*- coding: utf-8 -*- from gimpfu import * # orientation: ORIENTATION ...
- Jenkins(7)- 解决Linux下忘记Jenkins密码
如果想从头学起Jenkins的话,可以看看这一系列的文章哦 https://www.cnblogs.com/poloyy/category/1645399.html admin密码未更改情况下 进入\ ...
- Spring AOP框架 AspectJ
1 AspectJ简介 v AspectJ是一个基于Java语言的AOP框架 v Spring2.0以后新增了对AspectJ切点表达式支持 v @AspectJ 是AspectJ1.5新增功能 ...