MSIL实用指南-局部变量的声明、保存和加载

小说:网贷内部渠道是真的吗作者:马海石公更新时间:2019-01-16字数:59080

白色毛发在三大增幅技能的作用下已经变成了灿金色。巨大的白虎真身上,充满了破坏性的爆炸式魂力,在唐三和宁荣荣的增幅下。戴沐白一头就钻进了海神之光中,开始了飞速地攀登。

云商宝代理

接下来便是十二号、十三号的拍品,对于这个叶扬就没有什么兴趣了,不过他还是参与其中,帮别人抬抬价似乎也不错。尤其是十三号拍品,那三号包间里的客人似乎非常想要得到这个东西,叶扬偏偏不能让他这名如愿。
大批鬼子炮兵接到命令后,穿戴上带着长长猪鼻子似的防毒面具,背着迫击炮赶到了前沿阵地上,此刻正好带着一个营的兄弟们赶到中华门城墙上的宪兵肖司令发现了城墙下那些鬼子炮兵,马上对手下喊道:“鬼子要放毒气!”

“……”琛哥和旗袍美妇白竹筠对视一眼,心想这小子的确厉害,处处算计在别人之前如果没有……那么还落进他的算计之中了。不过,现在正好就坡下驴。美人计照用!

这一篇讲解方法内的局部变量是怎么声明、怎样保存、怎样加载的。

声明局部变量
声明用ILGenerator的DeclareLocal方法,参数是局部变量的数据类型,得到一个局部变量对应的创建类LocalBuilder。
使用格式是
LocalBuilder localBuilderx = ilGenerator.DeclareLocal(typeof(<数据类型>));
实际例子

LocalBuilder localBuilderv1 = ilGenerator.DeclareLocal(typeof(string));//声明一个string类型局部变量
LocalBuilder localBuilderv2 = ilGenerator.DeclareLocal(typeof(int));//声明一个int类型局部变量

LocalBuilder对象有两个重要的属性LocalType和LocalIndex。
属性LocalType的数据类型是System.Type,它表示的是这个局部变量的数据类型。
属性LocalIndex是int类型,它表示的是这个局部变量在这个方法体内的局部变量索引,并且是从0 开始的;假如这个局
部变量所在方法体的ilGenerator第n次调用DeclareLocal方法,那么它的LocalIndex就是(n-1)。

保存局部变量
保存局部变量的指令是Stloc、Stloc_S、Stloc_0、Stloc_1、Stloc_2、Stloc_3。
Stloc是通用指令;
当LocalBuilder的LocalIndex在0到255之间时,推荐用Stloc_S;
当LocalBuilder的LocalIndex为0时,推荐用Stloc_0;
当LocalBuilder的LocalIndex为1时,推荐用Stloc_1;
当LocalBuilder的LocalIndex为2时,推荐用Stloc_2;
当LocalBuilder的LocalIndex为3时,推荐用Stloc_3。
可以把这些指令用一个方法进行包装,源码如下

public static void StormLocal(ILGenerator ilGenerator, LocalBuilder localBuilder)
        {
            int localIndex = localBuilder.LocalIndex;
            switch (localIndex)
            {
                case 0:
                    ilGenerator.Emit(OpCodes.Stloc_0);
                    return;
                case 1:
                    ilGenerator.Emit(OpCodes.Stloc_1);
                    return;
                case 2:
                    ilGenerator.Emit(OpCodes.Stloc_2);
                    return;
                case 3:
                    ilGenerator.Emit(OpCodes.Stloc_3);
                    return;
            }
            if (localIndex > 0 && localIndex <= 255)
            {
                ilGenerator.Emit(OpCodes.Stloc_S, localIndex);
                return;
            }
            else
            {
                ilGenerator.Emit(OpCodes.Stloc, localIndex);
                return;
            }
        }

 

加载局部变量
把局部变量加载到运算栈上的指令是Ldloc、Ldloc_S、Ldloc_0、Ldloc_1、Ldloc_2、Ldloc_3。
Ldloc是通用指令;
当LocalBuilder的LocalIndex在0到255之间时,推荐用Ldloc_S;
当LocalBuilder的LocalIndex为0时,推荐用Ldloc_0;
当LocalBuilder的LocalIndex为1时,推荐用Ldloc_1;
当LocalBuilder的LocalIndex为2时,推荐用Ldloc_2;
当LocalBuilder的LocalIndex为3时,推荐用Ldloc_3。
可以把这些指令用一个方法进行包装,源码如下

        public static void LoadLocal(ILGenerator ilGenerator,LocalBuilder localBuilder)
        {
            int localIndex = localBuilder.LocalIndex;
            switch (localIndex)
            {
                case 0:
                    ilGenerator.Emit(OpCodes.Ldloc_0);
                    return;
                case 1:
                    ilGenerator.Emit(OpCodes.Ldloc_1);
                    return;
                case 2:
                    ilGenerator.Emit(OpCodes.Ldloc_2);
                    return;
                case 3:
                    ilGenerator.Emit(OpCodes.Ldloc_3);
                    return;
            }
            if(localIndex>0 && localIndex<=255)
            {
                ilGenerator.Emit(OpCodes.Ldloc_S, localIndex);
                return;
            }
            else
            {
                ilGenerator.Emit(OpCodes.Ldloc, localIndex);
                return;
            }
        }

完整的程序如下

using System;
using System.Reflection;
using System.Reflection.Emit;

namespace LX1_ILDemo
{
    class Demo04_Local
    {
        static string binaryName = "Demo04_Local.exe";
        static string namespaceName = "LX1_ILDemo";
        static string typeName = "EmitLocal";

        static AssemblyBuilder assemblyBuilder;
        static ModuleBuilder moduleBuilder;
        static TypeBuilder typeBuilder;
        static MethodBuilder mainMethod;
        static ILGenerator ilGenerator;

        static void Emit_ILCode()
        {
            MethodInfo writeIntLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
            MethodInfo writeStringLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });

            /* string v1; */
            LocalBuilder localBuilderv1 = ilGenerator.DeclareLocal(typeof(string));//声明一个string类型局部变量,第一次声明一个变量,所以它的LocalIndex是0

            /* v1="hello"; */
            ilGenerator.Emit(OpCodes.Ldstr,"hello");
            ilGenerator.Emit(OpCodes. Stloc_0 );
            /* Console.WriteLine(v1); */
            ilGenerator.Emit(OpCodes.Ldloc_0);
            ilGenerator.Emit(OpCodes.Call, writeStringLineMethod);

            /* v1="hello"; */
            ilGenerator.Emit(OpCodes.Ldstr, "world");
            StormLocal(ilGenerator, localBuilderv1);
            /* Console.WriteLine(v1); */
            LoadLocal(ilGenerator, localBuilderv1);
            ilGenerator.Emit(OpCodes.Call, writeStringLineMethod);


            /* int v2; */
            LocalBuilder localBuilderv2 = ilGenerator.DeclareLocal(typeof(int));//声明一个int类型局部变量,第二次声明一个变量,所以它的LocalIndex是1

            /* v2=int.MaxValue; */
            ilGenerator.Emit(OpCodes.Ldc_I4,int.MaxValue);
            ilGenerator.Emit(OpCodes.Stloc_1);
            /* Console.WriteLine(v2); */
            ilGenerator.Emit(OpCodes.Ldloc_1);
            ilGenerator.Emit(OpCodes.Call, writeIntLineMethod);


            /* v1=int.MinValue; */
            ilGenerator.Emit(OpCodes.Ldc_I4, int.MinValue);
            StormLocal(ilGenerator, localBuilderv2);
            /* Console.WriteLine(v2); */
            LoadLocal(ilGenerator, localBuilderv2);
            ilGenerator.Emit(OpCodes.Call, writeIntLineMethod);

        }

        public static void LoadLocal(ILGenerator ilGenerator,LocalBuilder localBuilder)
        {
            int localIndex = localBuilder.LocalIndex;
            switch (localIndex)
            {
                case 0:
                    ilGenerator.Emit(OpCodes.Ldloc_0);
                    return;
                case 1:
                    ilGenerator.Emit(OpCodes.Ldloc_1);
                    return;
                case 2:
                    ilGenerator.Emit(OpCodes.Ldloc_2);
                    return;
                case 3:
                    ilGenerator.Emit(OpCodes.Ldloc_3);
                    return;
            }
            if(localIndex>0 && localIndex<=255)
            {
                ilGenerator.Emit(OpCodes.Ldloc_S, localIndex);
                return;
            }
            else
            {
                ilGenerator.Emit(OpCodes.Ldloc, localIndex);
                return;
            }
        }


        public static void StormLocal(ILGenerator ilGenerator, LocalBuilder localBuilder)
        {
            int localIndex = localBuilder.LocalIndex;
            switch (localIndex)
            {
                case 0:
                    ilGenerator.Emit(OpCodes.Stloc_0);
                    return;
                case 1:
                    ilGenerator.Emit(OpCodes.Stloc_1);
                    return;
                case 2:
                    ilGenerator.Emit(OpCodes.Stloc_2);
                    return;
                case 3:
                    ilGenerator.Emit(OpCodes.Stloc_3);
                    return;
            }
            if (localIndex > 0 && localIndex <= 255)
            {
                ilGenerator.Emit(OpCodes.Stloc_S, localIndex);
                return;
            }
            else
            {
                ilGenerator.Emit(OpCodes.Stloc, localIndex);
                return;
            }
        }

        public static void Generate()
        {
            InitAssembly();

            /* 生成 public class LoadLFDSN */
            typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public);

            /* 生成 public static void Main() */
            GenerateMain();

            Emit_ILCode();

            EmitReadKey();
            ilGenerator.Emit(OpCodes.Ret);

            /*  设置assembly入口方法 */
            assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);

            SaveAssembly();
            Console.WriteLine("生成成功");
        }

        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

 

编辑:石建董

发布:2019-01-16 00:00:10

当前文章:http://www.leetaemin.cn/news2018092510191/

卡梦金融代理 91好信官网 梦者时代网贷推广返点app 祥源财推返现平台 卡享时代怎么代理 非凡网贷推广 介绍客户拿佣金 贷款口子平台系统

87478 52974 77555 39901 42364 7530471419 53963 75923

我要说两句: (0人参与)

发布