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 ... ...
随机推荐
- JDBC基础篇(MYSQL)——使用statement执行DML语句(insert/update/delete)
注意:其中的JdbcUtil是我自定义的连接工具类:代码例子链接: package day02_statement; import java.sql.Connection; import java.s ...
- 刷题-力扣-剑指 Offer 15. 二进制中1的个数
剑指 Offer 15. 二进制中1的个数 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de- ...
- Vue.JS快速上手(Vue-router 实现SPA 开发)
一.什么是路由 URL -> 映射 -> 组件 Hash+onhashchange History.pushstate+replaceState+onpopstate 二.准备工作 组件 ...
- ES6扩展——对象的扩展(简洁表示法与属性名表达式)
1.简洁表达法. 当属性名与属性值相同时,可省略属性值:例如:{name : name}可以写成 {name} 属性方法中,可省略冒号与function,直接 属性名(){}即可.例如{say : f ...
- Mybatis笔记(2)
一.Mybatis的Dao层实现 1.1 代理开发方式介绍 Mapper 接口开发需要遵循以下规范: 1. Mapper.xml文件中的namespace与mapper接口的全限定名相同 2. Map ...
- 集合框架3-Arrays 类
Arrays 和 Collections是分别操作数组和集合的两个工具类.今天就来对 Arrays 中的内容作个总结. 一.Arrays 类概述 Arrays 类位于 java.util包中.Arra ...
- Linux--MySQL 日志管理、备份与恢复
MySQL 日志管理.备份与恢复一.MySQL 日志管理二.数据库备份的重要性与分类 1.数据备份的重要性 2.从物理与逻辑的角度,备份分为 3.从数据库的备份策略角度,备份可分为三.常见的备份 ...
- Identity用户管理入门二(显示用户列表)
在Controllers中新建AccountController,并在构造方法(函数)中注入SignInManager,UserManager UserManager 用户管理(注册,查找,修改, ...
- 源码编译安装 LNMP及论坛
一.安装Nginx服务 systemctl stop firewalld systemctl disable firewalld setenforce 0 1.安装依赖包 yum -y install ...
- Kubernetes-Pod介绍(二)-生命周期
前言 本篇是Kubernetes第五篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战. Kubernetes系列文章: Kubernetes介绍 Kubernetes环境搭建 Kuberne ...