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
    

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

  • 相关阅读:
    io流
    JDBC-java数据库连接
    list接口、set接口、map接口、异常
    集合、迭代器、增强for
    math类和biginteger类
    基本包装类和System类
    正则表达式
    API-Object-equals方法和toString方法 Strinig字符串和StingBuffer类
    匿名对象 内部类 包 访问修饰符 代码块
    final 和 static 关键词
  • 原文地址:https://www.cnblogs.com/yyfh/p/13332835.html
Copyright © 2011-2022 走看看