zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    C#判断网络链接状态
    C# 创建临时文件(转帖)
    C# 很久以前几个常用类
    正则附表
    如何判断WebBrowser浏览器网页加载完成
    控件阴影
    C# 使用WM_COPYDATA传输数据(两个窗体间通信)
    C# 调用POST请求
    改变无边框窗体的尺寸大小和移动无边框窗体
    IT学习网站
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8567454.html
Copyright © 2011-2022 走看看