Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

IL switch instruction

I am researching IL code which generated from this C# code (RELEASE):

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;
}

IL:

//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

Why "switch" in IL works with sequence (1,2,3… n+1) and do not add other values (for exapmle: for 15 generated 3 instruction (001f, 0020, 0022))

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

//Why not "switch(IL_0026, IL_002c, IL_0032, IL_0038)"?

Because that 4th label would be jumped to if the value of a was 4, not 15. The jump targets in a switch correspond to successive values of the tested value.

In order to use switch and not have the additional special case for 15, it would need to be:

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)

(I hope I’ve counted right)

Which would be a much larger jump table.


I’d always recommend checking out the documentation for Reflection.Emit for the instruction you’re looking at, e.g. OpCodes.Switch, to make sure you understand what the instruction does.

The switch instruction pops a value off the stack and compares it, as an unsigned integer, to N. If value is less than N, execution is transferred to the target indexed by value, where targets are numbered from 0 (for example, a value of 0 takes the first target, a value of 1 takes the second target, and so on).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading