前言 在C#中提供了一些關鍵字if、else、switch、for等,這些關鍵字為我們提供了應用程式的流程式控制制。後面幾個章節我們將看到的是流程式控制制在IL中的實現。 static void Main(string[] args) { var a = 1; if (a == 0) { Console.W ...
前言
在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
上面是不是很簡單,大家可以根據相關代碼看一下,這個還是相對來說比較簡單地他並沒有摻雜著非同步和委托,在後面我們會看到其他代碼的示例和介紹。