zoukankan      html  css  js  c++  java
  • MSIL入门(三)之流程控制

    前言

    在C#中提供了一些关键字if、else、switch、for等,这些关键字为我们提供了应用程序的流程控制。后面几个章节我们将看到的是流程控制在IL中的实现。

        static void Main(string[] args)
            {
                var a = 1;
                if (a == 0)
                {
                    Console.WriteLine("0");
                }
                else if (a == 1)
                {
                    Console.WriteLine("1");
                }
                else
                {
                    Console.WriteLine("...");
                }
            }
    

    Ceq 比较两个值。如果这两个值相等,则将整数值 1 (int32) 推送到计算堆栈上;否则,将0 (int32) 推送到计算堆栈上。

    brfalse 表示计算栈上的值为 false/null/0 时发生跳转

    brtrue 表示计算栈上的值为 true/非空/非0 时发生跳转

    br.s 无条件的跳转到 x 标签所在的IL指令

     .method private hidebysig static void
        Main(
          string[] args
        ) cil managed
      {
        .entrypoint //主函数,程序的入口
        .maxstack 2 //栈的最大深度
        .locals init (
          [0] int32 a,
          [1] bool V_1,
          [2] bool V_2
        ) //本地变量定义
    
        // [8 9 - 8 10] 、
         
        IL_0000: nop //什么都不做
    
        // [9 13 - 9 23]
        IL_0001: ldc.i4.1  //把V_1的值放到计算堆栈上
        IL_0002: stloc.0     //把计算堆栈顶部的值(a)放到调用堆栈索引0处
    
        // [10 13 - 10 24]
        IL_0003: ldloc.0      //把调用堆栈索引为0处的值复制到计算堆栈
        IL_0004: ldc.i4.0 //把0放到计算堆栈上
        IL_0005: ceq //比较两个值是否相等,并把值存入堆栈
        IL_0007: stloc.1 //把计算堆栈顶部的值(V_1)放到调用堆栈索引1处
    
        IL_0008: ldloc.1  //把计算堆栈顶部的值(V_1)放到调用堆栈索引1处
        IL_0009: brfalse.s    IL_001a //表示计算栈上的值为 false/null/0,则跳转跳转到IL_001a标签所在的位置
    
        // [11 13 - 11 14]
        IL_000b: nop //什么都不做
    
        // [12 17 - 12 40]
        IL_000c: ldstr        "0" //将字符串"0"存入到堆栈
        IL_0011: call         void [System.Console]System.Console::WriteLine(string) //调用System.Console::WriteLine方法
        IL_0016: nop //什么都不做
    
        // [13 13 - 13 14]
        IL_0017: nop //什么都不做
        IL_0018: br.s         IL_003e //跳转到IL_003e
    
        // [14 18 - 14 29]
        IL_001a: ldloc.0      //把计算堆栈顶部的值(a)放到调用堆栈索引1处
        IL_001b: ldc.i4.1 //把1放到计算堆栈上
        IL_001c: ceq //比较两个值是否相等,并把值存入堆栈
        IL_001e: stloc.2      //把计算堆栈顶部的值(V_2)放到调用堆栈索引2处
    
        IL_001f: ldloc.2      //把计算堆栈顶部的值(V_2)放到调用堆栈索引3处  
        IL_0020: brfalse.s    IL_0031  //表示计算栈上的值为 false/null/0,则跳转跳转到IL_0031标签所在的位置
    
        // [15 13 - 15 14]
        IL_0022: nop //什么都不做
    
        // [16 17 - 16 40]
        IL_0023: ldstr        "1" //将字符串"1"存入到堆栈
        IL_0028: call         void [System.Console]System.Console::WriteLine(string) //调用System.Console::WriteLine方法
        IL_002d: nop //什么都不做
    
        // [17 13 - 17 14]
        IL_002e: nop //什么都不做
        IL_002f: br.s         IL_003e  //跳转到IL_003e
    
        // [19 13 - 19 14]
        IL_0031: nop //什么都不做
    
        // [20 17 - 20 42]
        IL_0032: ldstr        "..." //将字符串"..."存入到堆栈
        IL_0037: call         void [System.Console]System.Console::WriteLine(string)
        //调用System.Console::WriteLine方法
        IL_003c: nop //什么都不做
    
        // [21 13 - 21 14]
        IL_003d: nop //什么都不做
    
        // [22 9 - 22 10]
        IL_003e: ret //retrun 
    
      } // end of method Program::Main
    

    上面是不是很简单,大家可以根据相关代码看一下,这个还是相对来说比较简单地他并没有掺杂着异步和委托,在后面我们会看到其他代码的示例和介绍。

  • 相关阅读:
    linux查看CPU和内存信息
    linux yum命令详解
    查看文件中关键字前后几行的内容
    vue.js+web storm安装及第一个vue.js
    android GPS: code should explicitly check to see if permission is available
    ASP.NET MVC Identity 使用自己的SQL Server数据库
    阿里云服务器,tomcat启动,一直卡在At least one JAR was scanned for TLDs yet contained no TLDs就不动了
    ASP.NET MVC4 MVC 当前上下文中不存在名称“Scripts”
    python 将windows字体中的汉字生成图片的方法
    Java android DES+Base64加密解密
  • 原文地址:https://www.cnblogs.com/yyfh/p/13332835.html
Copyright © 2011-2022 走看看