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) 推送到計算堆棧上。ide

brfalse 表示計算棧上的值爲 false/null/0 時發生跳轉函數

brtrue 表示計算棧上的值爲 true/非空/非0 時發生跳轉3d

br.s 無條件的跳轉到 x 標籤所在的IL指令code

.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

上面是否是很簡單,你們能夠根據相關代碼看一下,這個仍是相對來講比較簡單地他並無摻雜着異步和委託,在後面咱們會看到其餘代碼的示例和介紹。索引

相關文章
相關標籤/搜索