首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IL开关指令

IL开关指令
EN

Stack Overflow用户
提问于 2022-01-19 10:24:06
回答 1查看 189关注 0票数 1

我正在研究从这个C#代码(Release)生成的IL代码:

代码语言:javascript
复制
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;
}

伊:

代码语言:javascript
复制
//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中的“开关”与序列(1,2,3.n+1)和不添加其他值(对于exapmle:对于生成的15条指令(001f,0020,0022))

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-19 10:34:06

//为什么不“交换(IL_0026,IL_002c,IL_0032,IL_0038)"?

因为如果a的值是4,而不是15,那么第4个标签就会被跳到。switch中的跳转目标对应于测试值的连续值。

为了使用switch而没有15的额外特例,需要:

代码语言:javascript
复制
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,以确保您理解该指令的功能。

开关指令从堆栈中弹出一个值,并将其作为无符号整数与N进行比较。如果值小于N,则执行转移到按值索引的目标,其中目标编号从0(例如,值0接受第一个目标,值1接受第二个目标,等等)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70768899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档