• MSIL实用指南-加载int值


    这一篇讲的是怎样加载整数值到运算栈上。这一类的指令都是以Ldc_I4开头。

    Ldc_I4
    类OpCodes的Ldc_I4字段的功能是把一个int值压入运算栈上。它的使用方法是
    ilGenerator.Emit(OpCodes.Ldc_I4, <整数值>);
    产生的指令是ldc.i4 <整数值>
    几个例子

    ilGenerator.Emit(OpCodes.Ldc_I4, 2000);//ldc.i4 2000
    ilGenerator.Emit(OpCodes.Ldc_I4, -100);//ldc.i4 -100
    ilGenerator.Emit(OpCodes.Ldc_I4, -1);//ldc.i4 -1
    

    Ldc_I4_S
    类OpCodes的Ldc_I4_S字段的功能是把一个将从-128 到 127 之间的整数值压入运算栈上。如果整数值小于0,则必须强制转换为sbyte。它的使用方法是
    ilGenerator.Emit(OpCodes.Ldc_I4_S <整数值>);
    产生的指令是ldc.i4 <整数值>
    几个例子

    ilGenerator.Emit(OpCodes.Ldc_I4_S, (SByte)(-1));//ldc.i4.s -1
    ilGenerator.Emit(OpCodes.Ldc_I4_S, 127);//ldc.i4.s 127
    ilGenerator.Emit(OpCodes.Ldc_I4_S, 0);//ldc.i4.s 0


    Ldc_I4_M1、Ldc_I4_0、Ldc_I4_1、Ldc_I4_2、Ldc_I4_3、Ldc_I4_4、Ldc_I4_5、Ldc_I4_6、Ldc_I4_7、Ldc_I4_8
    Ldc_I4_M1作用是将-1推送到计算堆栈上,Ldc_I4_0作用是将0推送到计算堆栈上,Ldc_I4_1作用是将1推送到计算堆栈上,Ldc_I4_2作用是将2推送到计算堆栈上,Ldc_I4_3作用是将3推送到计算堆栈上,Ldc_I4_4作用是将4推送到计算堆栈上,Ldc_I4_5作用是将5推送到计算堆栈上,Ldc_I4_6作用是将6推送到计算堆栈上,Ldc_I4_7作用是将7推送到计算堆栈上,Ldc_I4_8作用是将8推送到计算堆栈上。

    它们的使用方法是

    ilGenerator.Emit(OpCodes.Ldc_I4_M1);//ldc.i4.m1
    ilGenerator.Emit(OpCodes.Ldc_I4_0);//ldc.i4.0
    ilGenerator.Emit(OpCodes.Ldc_I4_1);//ldc.i4.1
    ilGenerator.Emit(OpCodes.Ldc_I4_2);//ldc.i4.2
    ilGenerator.Emit(OpCodes.Ldc_I4_3);//ldc.i4.3
    ilGenerator.Emit(OpCodes.Ldc_I4_4);//ldc.i4.4
    ilGenerator.Emit(OpCodes.Ldc_I4_5);//ldc.i4.5
    ilGenerator.Emit(OpCodes.Ldc_I4_6);//ldc.i4.6
    ilGenerator.Emit(OpCodes.Ldc_I4_7);//ldc.i4.7
    ilGenerator.Emit(OpCodes.Ldc_I4_8);//ldc.i4.8

    ilGenerator.Emit(OpCodes.Ldc_I4_M1)和ilGenerator.Emit(OpCodes.Ldc_I4, -1)、ilGenerator.Emit(OpCodes.Ldc_I4_S, (SByte)(-1))运行的结果是一条的,但是效率更高;同样的ilGenerator.Emit(OpCodes.Ldc_I4_0)和ilGenerator.Emit(OpCodes.Ldc_I4, 0)、ilGenerator.Emit(OpCodes.Ldc_I4_S, 0)运行结果一样,效率更高,等等。
    在-128 到 127 之间的整数值用Ldc_I4_S比Ldc_I4更好。
    所以可以把加载整数值用一个方法代替

            public static void LoadInt(ILGenerator il, int value)
            {
                switch (value)
                {
                    case -1:
                        il.Emit(OpCodes.Ldc_I4_M1);
                        return;
                    case 0:
                        il.Emit(OpCodes.Ldc_I4_0);
                        return;
                    case 1:
                        il.Emit(OpCodes.Ldc_I4_1);
                        return;
                    case 2:
                        il.Emit(OpCodes.Ldc_I4_2);
                        return;
                    case 3:
                        il.Emit(OpCodes.Ldc_I4_3);
                        return;
                    case 4:
                        il.Emit(OpCodes.Ldc_I4_4);
                        return;
                    case 5:
                        il.Emit(OpCodes.Ldc_I4_5);
                        return;
                    case 6:
                        il.Emit(OpCodes.Ldc_I4_6);
                        return;
                    case 7:
                        il.Emit(OpCodes.Ldc_I4_7);
                        return;
                    case 8:
                        il.Emit(OpCodes.Ldc_I4_8);
                        return;
                }
    
                if (value > -129 && value < 128)
                {
                    il.Emit(OpCodes.Ldc_I4_S, (SByte)value);
                }
                else
                {
                    il.Emit(OpCodes.Ldc_I4, value);
                }
            }
    

      

    完整的程序如下

    using System;
    using System.Reflection;
    using System.Reflection.Emit;
    
    namespace LX1_ILDemo
    {
        class Demo1_LoadIntIL
        {
            static string binaryName = "LoadIntDemo.exe";
            static string namespaceName = "LX1_ILDemo";
            static string typeName = "LoadInt";
    
            static AssemblyBuilder assemblyBuilder;
            static ModuleBuilder moduleBuilder;
            static TypeBuilder typeBuilder;
            static MethodBuilder mainMethod;
            static ILGenerator ilGenerator;
            static MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
    
            public static void LoadInt(ILGenerator il, int value)
            {
                switch (value)
                {
                    case -1:
                        il.Emit(OpCodes.Ldc_I4_M1);
                        return;
                    case 0:
                        il.Emit(OpCodes.Ldc_I4_0);
                        return;
                    case 1:
                        il.Emit(OpCodes.Ldc_I4_1);
                        return;
                    case 2:
                        il.Emit(OpCodes.Ldc_I4_2);
                        return;
                    case 3:
                        il.Emit(OpCodes.Ldc_I4_3);
                        return;
                    case 4:
                        il.Emit(OpCodes.Ldc_I4_4);
                        return;
                    case 5:
                        il.Emit(OpCodes.Ldc_I4_5);
                        return;
                    case 6:
                        il.Emit(OpCodes.Ldc_I4_6);
                        return;
                    case 7:
                        il.Emit(OpCodes.Ldc_I4_7);
                        return;
                    case 8:
                        il.Emit(OpCodes.Ldc_I4_8);
                        return;
                }
    
                if (value > -129 && value < 128)
                {
                    il.Emit(OpCodes.Ldc_I4_S, (SByte)value);
                }
                else
                {
                    il.Emit(OpCodes.Ldc_I4, value);
                }
            }
    
            /// <summary>
            /// Ldc_I4_*类指令生成
            /// </summary>
            static void Emit_Ldc_I4_X()
            {
                /* 生成 Console.WriteLine(-1); */
                ilGenerator.Emit(OpCodes.Ldc_I4_M1);//ldc.i4.m1
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(0); */
                ilGenerator.Emit(OpCodes.Ldc_I4_0);//ldc.i4.0
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(1); */
                ilGenerator.Emit(OpCodes.Ldc_I4_1);//ldc.i4.1
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(2); */
                ilGenerator.Emit(OpCodes.Ldc_I4_2);//ldc.i4.2
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(3); */
                ilGenerator.Emit(OpCodes.Ldc_I4_3);//ldc.i4.3
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(4); */
                ilGenerator.Emit(OpCodes.Ldc_I4_4);//ldc.i4.4
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(5); */
                ilGenerator.Emit(OpCodes.Ldc_I4_5);//ldc.i4.5
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(6); */
                ilGenerator.Emit(OpCodes.Ldc_I4_6);//ldc.i4.6
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(7); */
                ilGenerator.Emit(OpCodes.Ldc_I4_7);//ldc.i4.7
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(8); */
                ilGenerator.Emit(OpCodes.Ldc_I4_8);//ldc.i4.8
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
            }
    
            static void Emit_Ldc_I4_S()
            {
                /* 生成 Console.WriteLine(-1); */
                ilGenerator.Emit(OpCodes.Ldc_I4_S, (SByte)(-1));//ldc.i4.s   -1
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(0); */
                ilGenerator.Emit(OpCodes.Ldc_I4_S, 0);//ldc.i4.s   0
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(8); */
                ilGenerator.Emit(OpCodes.Ldc_I4_S, 8);//ldc.i4.s   8
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(100); */
                ilGenerator.Emit(OpCodes.Ldc_I4_S, 100);//ldc.i4.s   100
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(127); */
                ilGenerator.Emit(OpCodes.Ldc_I4_S, 127);//ldc.i4.s   127
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(-128); */
                ilGenerator.Emit(OpCodes.Ldc_I4_S, (SByte) (- 128));//ldc.i4.s   -128
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
            }
    
            static void Emit_Ldc_I4()
            {
                /* 生成 Console.WriteLine(-1); */
                ilGenerator.Emit(OpCodes.Ldc_I4, -1);//ldc.i4   -1
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(0); */
                ilGenerator.Emit(OpCodes.Ldc_I4, 0);//ldc.i4   0
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(8); */
                ilGenerator.Emit(OpCodes.Ldc_I4, 8);//ldc.i4   8
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(-100); */
                ilGenerator.Emit(OpCodes.Ldc_I4, -100);//ldc.i4   -100
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(127); */
                ilGenerator.Emit(OpCodes.Ldc_I4, 127);//ldc.i4   127
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(-128); */
                ilGenerator.Emit(OpCodes.Ldc_I4, (-128));//ldc.i4   -128
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
    
                /* 生成 Console.WriteLine(2000); */
                ilGenerator.Emit(OpCodes.Ldc_I4, 2000);//ldc.i4   2000
                ilGenerator.Emit(OpCodes.Call, writeLineMethod);
            }
    
            public static void Generate()
            {
                InitAssembly();
    
                /* 生成 public class LoadInt */
                typeBuilder = moduleBuilder.DefineType( namespaceName+"."+ typeName, TypeAttributes.Public);
    
                /* 生成 public static void Main() */
                GenerateMain();
    
                Emit_Ldc_I4_X();
                Emit_Ldc_I4_S();
                Emit_Ldc_I4();
    
                EmitReadKey();
                ilGenerator.Emit(OpCodes.Ret);
    
                /*  设置assembly入口方法 */
                assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);
    
                SaveAssembly();
                Console.WriteLine("生成成功");
                //Console.ReadKey();
            }
    
            static void EmitReadKey()
            {
                /* 生成 Console.ReadKey(); */
                MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
                ilGenerator.Emit(OpCodes.Call, readKeyMethod);
                ilGenerator.Emit(OpCodes.Pop);
            }
    
            static void GenerateMain()
            {
                mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] { });
                ilGenerator = mainMethod.GetILGenerator();
            }
    
            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
  • 相关阅读:
    Service Name Port Number Transport Protocol tcp udp 端口号16bit
    linux linux 互传文件 win 不通过 ftp sftp 往linux 传文件(文件夹)
    soft deletion Google SRE 保障数据完整性的手段
    Taylor series
    Taylor's theorem
    Moving average
    REQUEST
    Unix file types
    mysqld.sock
    Tunneling protocol
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8567454.html
Copyright © 2020-2023  润新知