我正在研究從此 C# 代碼 ( RELEASE ) 生成的 IL 代碼:
int a = Convert.ToInt32(Console.ReadLine());
switch(a)
{
case 1: Console.WriteLine(); break;
case 2: Console.WriteLine(); break;
case 3: Console.WriteLine(); break;
case 15: Console.WriteLine(); break;
default: Console.WriteLine(); break;
}
伊利諾伊:
//Why not "switch(IL_0026, IL_002c, IL_0032, IL_0038)"?
IL_000e: switch (IL_0026, IL_002c, IL_0032)
IL_001f: ldloc.0
IL_0020: ldc.i4.s 15
IL_0022: beq.s IL_0038
IL_0024: br.s IL_003e
IL_0026: call void [System.Console]System.Console::WriteLine()
IL_002b: ret
IL_002c: call void [System.Console]System.Console::WriteLine()
IL_0031: ret
IL_0032: call void [System.Console]System.Console::WriteLine()
IL_0037: ret
IL_0038: call void [System.Console]System.Console::WriteLine()
IL_003d: ret
IL_003e: call void [System.Console]System.Console::WriteLine()
IL_0043: ret
為什么 IL 中的“switch”與序列 (1,2,3...n 1) 一起使用并且不添加其他值(例如:對于 15 生成的 3 指令 (001f, 0020, 0022))
uj5u.com熱心網友回復:
//Why not "switch(IL_0026, IL_002c, IL_0032, IL_0038)"?
因為如果 的值為 4,而不是 15,則將跳轉到第 4 個標簽。a 中a的跳轉目標switch對應于測驗值的連續值。
為了使用switch并且沒有額外的特殊情況15,它需要是:
switch(IL_0026, IL_002c, IL_0032, IL_003e, IL_003e, IL_003e, IL_003e, IL_003e, IL_003e, IL_003e, IL_003e, IL_003e, IL_003e, IL_003e, IL_0038)
(希望我數對了)
這將是一個更大的跳臺。
我總是建議您查看Reflection.Emit您正在查看的指令的檔案,例如OpCodes.Switch,以確保您了解該指令的作用。
switch 指令從堆疊中彈出一個值,并將其作為無符號整數與
N. 如果 value 小于N,則將執行轉移到按 value 索引的目標,其中目標從 0 開始編號(例如,值 0 表示第一個目標,值 1 表示第二個目標,依此類推)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/415678.html
標籤:
