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 ... ...
随机推荐
- [转]VRRP协议详解
原文地址:VRRP协议详解 文中涉及缩略语 缩略语 英文全名 中文解释 VRRP Virtual Router Redundancy Protocol 虚拟路由器冗余协议 NQA Network Qu ...
- msyql redo log和binlog
更新语句执行流程 下面是这个表的创建语句,这个表有一个主键 ID 和一个整型字段 c: create table T(ID int primary key, c int); 如果要将 ID=2 这一行 ...
- Qt中的Q_PROPERTY宏浅析
1. Q_PROPERTY Qt提供了一个绝妙的属性系统,Q_PROPERTY()是一个宏,用来在一个类中声明一个属性property,由于该宏是qt特有的,需要用moc进行编译,故必须继承于QObj ...
- 浅析mybatis中${}和#{}取值区别
mybatis作为一个轻量级的ORM框架,应用广泛,其上手使用也比较简单:一个成熟的框架,必然有精巧的设计,值得学习. 在使用mybatis框架时,在sql语句中获取传入的参数有如下两种方式: ${p ...
- Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用
原文地址 Jetpack Compose学习(4)--Image(图片)使用及Coil图片异步加载库使用 | Stars-One的杂货小窝 本篇讲解下关于Image的使用及使用Coil开源库异步加载网 ...
- Linux内核下包过滤框架——iptables&netfilter
iptables & netfilter 1.简介 netfilter/iptables(下文中简称为iptables)组成Linux内核下的包过滤防火墙,完成封包过滤.封包重定向和网络地址转 ...
- Datagird样式
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x=&qu ...
- 深入xLua实现原理之Lua如何调用C#
xLua是腾讯的一个开源项目,为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力.本文主要是探讨xLua下Lua调用C#的实现原理. Lua与C#数据通信机制 无论是Lua调用C# ...
- 深度学习——前向传播算法和反向传播算法(BP算法)及其推导
1 BP算法的推导 图1 一个简单的三层神经网络 图1所示是一个简单的三层(两个隐藏层,一个输出层)神经网络结构,假设我们使用这个神经网络来解决二分类问题,我们给这个网络一个输入样本,通过前向运算得到 ...
- PTA 面向对象程序设计 6-3 面积计算器(函数重载)
6-3 面积计算器(函数重载) 实现一个面积计算器,它能够计算矩形或长方体的面积. 函数接口定义: int area(int x, int y); int area(int x, int y, int ...