2020-07-17

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

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

MSIL入门(三)之流程控制acca是什么特许金融分析师houzz关注|大润发、家乐福等29家疫情期哄抬物价被罚名单公布!2018年prime day战报:销量破1亿,各国最畅销产品出炉!疫情下的网红营销现状与趋势去香港旅游适合穿什么衣服 香港旅游天气季节变化介绍我们去香港旅游用什么手机卡 香港电话和通讯服务介绍香港旅游购物注意事项 香港游有哪些购物热点好去处

No comments:

Post a Comment