• MSIL实用指南-位运算


    C#支持的位运算是与、或、异或、取反、左移、右移,它们对应的指令是
    And、Or、Xor、Not、Shl、Shr。

    取反运算只需要一个操作数,生成步骤是
    1.生成加载变量
    2.生成取反指令
    实例代码:

    ilGenerator.Emit(OpCodes.Ldarg_0);
    ilGenerator.Emit(OpCodes.Not);

    其它五个运算都需要两个参数,它们的通用步骤
    1.生成加载左边变量
    2.生成加载右边变量
    3.生成运算指令

    实例:

    ilGenerator.Emit(OpCodes.Ldarg_0);
    ilGenerator.Emit(OpCodes.Ldarg_1);
    ilGenerator.Emit(OpCodes.And);

    完整的程序如下:

    using System;
    using System.Reflection;
    using System.Reflection.Emit;
    
    namespace LX1_ILDemo
    {
        class Demo17_BitOP
        {
            static string binaryName = "Demo17_BitOP.exe";
            static string namespaceName = "LX1_ILDemo";
            static string typeName = "BitOPDemo";
    
            static AssemblyBuilder assemblyBuilder;
            static ModuleBuilder moduleBuilder;
            static TypeBuilder typeBuilder;
            static MethodBuilder mainMethod;
            static MethodBuilder testMethod;
    
            static void Emit_Test()
            {
                testMethod = typeBuilder.DefineMethod("TestOP", MethodAttributes.Public
                    | MethodAttributes.Static, typeof(void), new Type[] { typeof(int), typeof(int) });
                var println = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
                var ilGenerator = testMethod.GetILGenerator();
    
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Not);
                ilGenerator.Emit(OpCodes.Call, println);
    
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldarg_1);
                ilGenerator.Emit(OpCodes.And);
                ilGenerator.Emit(OpCodes.Call, println);
    
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldarg_1);
                ilGenerator.Emit(OpCodes.Or);
                ilGenerator.Emit(OpCodes.Call, println);
    
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldarg_1);
                ilGenerator.Emit(OpCodes.Xor);
                ilGenerator.Emit(OpCodes.Call, println);
    
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldc_I4_2);
                ilGenerator.Emit(OpCodes.Shl);
                ilGenerator.Emit(OpCodes.Call, println);
    
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldc_I4_2);
                ilGenerator.Emit(OpCodes.Shr);
                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,1000);
                ilGenerator.Emit(OpCodes.Ldc_I4,120);
                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
  • 相关阅读:
    821. 字符的最短距离
    1122. 数组的相对排序
    258. 各位相加
    C++常见问题之二#define使用中的陷阱
    python进阶二_基本数据类型与操作
    DirectX10一变换(三)
    Android中编译工具链的改动----LLVM份量的增加
    DirectX10一矩阵代数(二)
    DirectX10一向量代数(一)
    基于asp.net + easyui框架,一步步学习easyui-datagrid——实现添加、编辑、删除(三)
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8675809.html
Copyright © 2020-2023  润新知