MSIL实用指南-比较运算
生活随笔
收集整理的這篇文章主要介紹了
MSIL实用指南-比较运算
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數值的比較就是大于、小于、等于、大于等于、小于等于、不等于,它們的運算結果都是布爾值。
大于、小于、等于有直接對應的指令,分別是Cgt、Clt、Ceq。
大于等于、小于等于、不等于沒有直接對應的指令,它的運算實現一般是取反。
大于、小于、等于需要兩個參數,它們的通用步驟
1.生成加載左邊變量
2.生成加載右邊變量
3.生成比較運算指令
生成等于比較的代碼實例:
ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Ceq);?
下面以生成大于等于為例子,講解一下怎么生成相應運算指令。
前兩個步驟還是生成加載左右參數。
“生成等于”其實就是“不大于”,按順序就是先比較是否是小于,然后把這個結果和false比較。
IL指令中0代表false。
即生成
?
小于等于則是進行大于比較,然后再和0比較
ilGenerator.Emit(OpCodes.Cgt); ilGenerator.Emit(OpCodes.Ldc_I4_0); ilGenerator.Emit(OpCodes.Ceq);?
不等于是先進行等于比較,然后看這個結果是否是false
ilGenerator.Emit(OpCodes.Ceq); ilGenerator.Emit(OpCodes.Ldc_I4_0); ilGenerator.Emit(OpCodes.Ceq);?
上面可以看出,最后兩條指令是固定的,都是和false比較,獲得最終結果。
完整的程序如下
using System; using System.Reflection; using System.Reflection.Emit;namespace LX1_ILDemo {class Demo19_CompareOP{static string binaryName = "Demo19_CompareOP.exe";static string namespaceName = "LX1_ILDemo";static string typeName = "CompareOPDemo";static AssemblyBuilder assemblyBuilder;static ModuleBuilder moduleBuilder;static TypeBuilder typeBuilder;static MethodBuilder mainMethod;static MethodBuilder testMethod;static void Emit_Test(){testMethod = typeBuilder.DefineMethod("TestCompare", MethodAttributes.Public| MethodAttributes.Static, typeof(void), new Type[] { typeof(int), typeof(int) });var println = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(bool) });var ilGenerator = testMethod.GetILGenerator();// > ilGenerator.Emit(OpCodes.Ldarg_0);ilGenerator.Emit(OpCodes.Ldarg_1);ilGenerator.Emit(OpCodes.Cgt);ilGenerator.Emit(OpCodes.Call, println);// < ilGenerator.Emit(OpCodes.Ldarg_0);ilGenerator.Emit(OpCodes.Ldarg_1);ilGenerator.Emit(OpCodes.Clt);ilGenerator.Emit(OpCodes.Call, println);// == ilGenerator.Emit(OpCodes.Ldarg_0);ilGenerator.Emit(OpCodes.Ldarg_1);ilGenerator.Emit(OpCodes.Ceq);ilGenerator.Emit(OpCodes.Call, println);//>= ilGenerator.Emit(OpCodes.Ldarg_0);ilGenerator.Emit(OpCodes.Ldarg_1);ilGenerator.Emit(OpCodes.Clt);ilGenerator.Emit(OpCodes.Ldc_I4_0);ilGenerator.Emit(OpCodes.Ceq);ilGenerator.Emit(OpCodes.Call, println);// <= ilGenerator.Emit(OpCodes.Ldarg_0);ilGenerator.Emit(OpCodes.Ldarg_1);ilGenerator.Emit(OpCodes.Cgt);ilGenerator.Emit(OpCodes.Ldc_I4_0);ilGenerator.Emit(OpCodes.Ceq);ilGenerator.Emit(OpCodes.Call, println);//!= ilGenerator.Emit(OpCodes.Ldarg_0);ilGenerator.Emit(OpCodes.Ldarg_1);ilGenerator.Emit(OpCodes.Ceq);ilGenerator.Emit(OpCodes.Ldc_I4_0);ilGenerator.Emit(OpCodes.Ceq);ilGenerator.Emit(OpCodes.Call, println);ilGenerator.Emit(OpCodes.Ret);}public static void Generate(){InitAssembly();typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public);Emit_Test();GenerateMain();assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);SaveAssembly();Console.WriteLine("生成成功");}static void GenerateMain(){mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public| MethodAttributes.Static, typeof(void), new Type[] { });var ilGenerator = mainMethod.GetILGenerator();ilGenerator.Emit(OpCodes.Ldc_I4_1);ilGenerator.Emit(OpCodes.Ldc_I4_7);ilGenerator.Emit(OpCodes.Call, testMethod);ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadKey", new Type[] { }));ilGenerator.Emit(OpCodes.Pop);ilGenerator.Emit(OpCodes.Ret);}static void InitAssembly(){AssemblyName assemblyName = new AssemblyName(namespaceName);assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, binaryName);}static void SaveAssembly(){Type t = typeBuilder.CreateType(); //完成Type,這是必須的 assemblyBuilder.Save(binaryName);}} } View Code?
轉載于:https://www.cnblogs.com/tkt2016/p/8708821.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的MSIL实用指南-比较运算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wireshark抓包分析tcp连接与断
- 下一篇: Django:ORM关系字段