IL合集

  • A+
所属分类:.NET技术
摘要

    由于之前写的表达式树合集,未编写任何注释且是以图片的形式展现给大家,在这里向各位看官道歉了,接下来为大家奉上新鲜出炉的香喷喷的IL合集,后面会持续更新,各位看官点关注不迷路,之前答应的手写IOC以及多线程合集,目前IOC方面的困难已经解决掉,就差怎么封装了,有想法的看官可以加QQ群6406277,四川观察就是我,多线程方面的后面demo写出来整理好之后,届时会为大家奉上。,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

好了,今天的分享就结束了,后续会持续更新,欢迎大家关注,