zoukankan      html  css  js  c++  java
  • MSIL实用指南-生成while语句


    本篇讲解怎样生成while语句。while语句是编程语言中很重要的循环语句,它的结构是
    while(<表达式>)
    <语句或语句块>

    当表达式的结果为true时就一直执行语句或语句块,否则就结束执行循环。
    while语句的生成步骤是这样的。

    一、声明两个跳转标签
    while只需要两个跳转标签,分别用在表示式指令之前和语句块指令之前。

    二、生成无条件跳转到表达式开始标签的指令
    这是固定的,只有一句话。

    三、标记语句块开始标签位置

    四、并且生成语句块指令

    五、标记表达式开始标签位置

    六、并且生成表达式指令

    七、生成Brtrue_S跳转到语句块开始标签的指令


    完整程序如下:

    using System;
    using System.Reflection;
    using System.Reflection.Emit;
    
    namespace LX1_ILDemo
    {
        class Demo25_While
        {
            static string binaryName = "Demo25_While.exe";
            static string namespaceName = "LX1_ILDemo";
            static string typeName = "DemoWhile";
    
            static AssemblyBuilder assemblyBuilder;
            static ModuleBuilder moduleBuilder;
            static TypeBuilder typeBuilder;
            static MethodBuilder mainMethod;
            static MethodBuilder testMethod;
    
            static void Emit_TestMethod()
            {
                testMethod = typeBuilder.DefineMethod("Test", MethodAttributes.Public
                   | MethodAttributes.Static, typeof(void), new Type[] { typeof(int)});
                ILGenerator ilGenerator = testMethod.GetILGenerator();
    
                Label labelConditionStart = ilGenerator.DefineLabel();
                Label labelBlockSart = ilGenerator.DefineLabel();
                MethodInfo writeIntLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
    
                ilGenerator.Emit(OpCodes.Br_S, labelConditionStart);
    
                ilGenerator.MarkLabel(labelBlockSart);
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Call, writeIntLineMethod);
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldc_I4_1);
                ilGenerator.Emit(OpCodes.Sub);
                ilGenerator.Emit(OpCodes.Starg_S, 0);
    
                ilGenerator.MarkLabel(labelConditionStart);
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldc_I4_0);
                ilGenerator.Emit(OpCodes.Cgt);
    
                ilGenerator.Emit(OpCodes.Brtrue_S, labelBlockSart);
    
                ilGenerator.Emit(OpCodes.Ret);
            }
             
            public static void Generate()
            {
                InitAssembly();
                typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public);
    
                Emit_TestMethod();
                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_S,(sbyte)10);
                ilGenerator.Emit(OpCodes.Call, testMethod);
         
                MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
                ilGenerator.Emit(OpCodes.Call, readKeyMethod);
                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
  • 相关阅读:
    Spring MVC Ajax 嵌套表单数据的提交
    Spring MVC 过滤静态资源访问
    Spring MVC 页面跳转时传递参数
    IDEA Maven 三层架构 2、运行 springMVC
    IDEA Maven 三层架构 1、基本的Archetype 搭建
    EasyUI DataGrid 基于 Ajax 自定义取值(loadData)
    Spring MVC Ajax 复杂参数的批量传递
    Mybatis Sql片段的应用
    在 Tomcat 8 部署多端口项目
    自动升级的设计思路与实现
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8778814.html
Copyright © 2011-2022 走看看