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 ... ...
随机推荐
- servlet中servletContext的五大作用(四)
1. 获取web的上下文路径 2. 获取全局的参数 3. 作为域对象使用 4. 请求转发 5. 读取web项目的资源文件 package day10.about_serv ...
- [Kotlin Tutorials 19] Kotlin Flows, SharedFlow and StateFlow in Android
Kotlin Flows 本文包含的内容: Flow是什么, 基本概念和用法. Flow的不同类型, StateFlow和SharedFlow比较. Flow在Android中的使用 安全收集. 操作 ...
- Go测试--性能测试分析
目录 前言 认识数据 benchstat 分析一组样本 分析两组样本 小结 前言 benchmark测试是实际项目中经常使用的性能测试方法,我们可以针对某个函数或者某个功能点增加benchmark测试 ...
- SSD算法原理
Paper: https://arxiv.org/pdf/1512.02325.pdf SSD用神经网络(VGG)提取多层feature map ,来实现对不同大小物体的检测.如下图所示: We us ...
- SpringBoot笔记(5)
一.Web原生组件注入 1.使用Servlet API @ServletComponentScan(basePackages = "com.atguigu.admin") :指定原 ...
- python之数据库编程
python之数据库编程 sqlite 1.前期准备工作 导入模块: import sqlite3 连接数据库 conn = sqlite3.connect("test.db") ...
- Python之pyyaml模块
pyyaml模块在python中用于处理yaml格式数据,主要使用yaml.safe_dump().yaml.safe_load()函数将python值和yaml格式数据相互转换.当然也存在yaml. ...
- jenkins AWS CodeDeploy不停机部署
此项目的特点是把Jenkins与CodeDeploy相结合做的CICD做的蓝绿发布,CI与CD 是分开的,CI构建完以后以BuildNumber的形式把war包存至AWS的S3桶中.同时在java项目 ...
- SpringBoot 属性配置文件数据注入配置和yml与properties区别
前言 我们知道SpringBoot 通过配置类来解放一堆的xml文件配置,通属性配置文件,来进行,系统全局属性配置,这样极大的简化了我们开发过程,java web 也可以甜甜的从此 快速配置 Spri ...
- Python - repr()、str() 的区别
总的来说 str():将传入的值转换为适合人阅读的字符串形式 repr():将传入的值转换为 Python 解释器可读取的字符串形式 传入整型 # number resp = str(1) print ...