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 ... ...
随机推荐
- 关于对String中intern方法的理解
在java的String中有个一直被我们忽视了的方法intern方法:它的官方解释是:一个初始时为空的字符串池,它由类 String 私有地维护. 当调用 intern 方法时,如果池已经包含一个等于 ...
- vivo全球商城时光机 - 大型促销活动保障利器
一.背景 官网商城在双11.双12等大促期间运营同学会精心设计许多给到用户福利的促销活动,当促销活动花样越来越多后就会涉及到很多的运营配置工作(如指定活动有效期,指定活动启停状态,指定活动参与商品等等 ...
- webpack编译后的代码如何在浏览器执行
浏览器是无法直接使用模块之间的commonjs或es6,webpack在打包时做了什么处理,才能让浏览器能够执行呢,往下看吧. 使用commonjs语法 先看下写的代码, app.js minus.j ...
- call bind apply的区别
call() 和apply()的第一个参数相同,就是指定的对象.这个对象就是该函数的执行上下文. call()和apply()的区别就在于,两者之间的参数. call()在第一个参数之后的 后续所有参 ...
- PC微信多开
1.桌面上面新建一个 多开.txt . 2.将下面的内容拷贝进去 TASKKILL /F /IM wechat.exestart "" "E:\wechat\WeCha ...
- MySQL-SQL基础-DCL
mysql> grant select,insert on sakila.* to 'zl'@'localhost' identified by '123'; Query OK, 0 rows ...
- SpringBoot笔记(4)
一.请求处理 1.1 常用参数注解使用 注解 使用 @PathVariable 获取URI模板指定请求,并赋值到变量中,不指定可以将所有请求放到map中,但是健值都为String @RequestHe ...
- IO流学习笔记(一)之FileWriter与FileReader
IO流用来处理设备之间的数据传输 Java对数据的操作是通过流的方式 Java用于操作流的对象都在IO包中 流按照操作数据分为两种:字节流和字符流 流按流向分为:输入流和输出流 输入流和输出流是相对于 ...
- 史上最全git命令集
配置化命令 git config --global user.name "Your Name" git config --global user.email "email ...
- WEB漏洞——CSRF、SSRF
CSRF漏洞 CSRF( Cross- site request forgery,跨站请求伪造)也被称为 One Click Attack或者 Session Riding,通常缩写为CSRF或者XS ...