Common Intermediate Language

Implementing a Loop

If anyone has ever touched any assembler then you will be aware of opcodes that do comparisons, this includes assembly languages like MIPS.

I present first the C# code of the for loop.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i);
            }
        }
    }
}

Now here is my implementation of the same using MSIL.

.assembly extern mscorlib {}

.assembly lesthan 
{ 
    .ver 1:0:0:0
}

.module LessThan.exe

.method static void main()
{
    .entrypoint
    .maxstack 2
    
    .locals init (int32, int32)

    ldc.i4 10
    stloc.0
    ldc.i4 0
    stloc.1
    
    Expr:
        ldloc.1
        ldloc.0
        blt Body
        ret
        
    Body:
        ldloc.1
        call void [mscorlib]System.Console::WriteLine(int32)
        ldc.i4 1
        ldloc.1
        add
        stloc.1
        br Expr
}

This code is pretty easy to disassemble.  I create a branch block that defines the expression (.Expr) i (where i is the current value in mem location 1) < 10 (location 0) if this expression is true then we branch to .Body which basically prints out the current value of i as well as incrementing that value by 1, we then check the expression holds true again - if so we go again, if not we return power to the caller.

There is a key difference between what the C# compiler will give you and what I have given you, the first is that I have used fairly meaningful branch names, and the second is that I have decided to initialize two local variables holding both the counter (initially 0) and the max (10) - the C# compiler in the above code will only create a local variable for i, 10 will be loaded onto the stack when required.

The C# compiler will honour the fact that 10 is not assigned to any variable so the below is a more accurate representation of what the compiler will generate us, i is a local variable where as the integer 10 is loaded onto the stack when the expression is evaluated.

.assembly extern mscorlib {}

.assembly lesthanC 
{ 
    .ver 1:0:0:0
}

.module LessThanC.exe

.method static void main()
{
    .entrypoint
    .maxstack 2 
    
    .locals init (int32)
    
    ldc.i4 0
    stloc.0
    
    Expr:
        ldloc.0
        ldc.i4 10
        blt Body
        ret
        
    Body:
        ldloc.0
        call void [mscorlib]System.Console::WriteLine(int32)
        ldc.i4 1
        ldloc.0
        add
        stloc.0
        br Expr
}

Here is in fact what the C# compiler generates for us (release mode, code optimization).

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       20 (0x14)
  .maxstack  2
  .locals init ([0] int32 i)
  IL_0000:  ldc.i4.0
  IL_0001:  stloc.0
  IL_0002:  br.s       IL_000e
  IL_0004:  ldloc.0
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_000a:  ldloc.0
  IL_000b:  ldc.i4.1
  IL_000c:  add
  IL_000d:  stloc.0
  IL_000e:  ldloc.0
  IL_000f:  ldc.i4.s   10
  IL_0011:  blt.s      IL_0004
  IL_0013:  ret
} // end of method Program::Main

Have a look at the MSIL.  We first store the int 0 onto the stack, then we branch to IL_000e - here we check that i < 10 if so we branch to IL_0004 where we load the value of i onto the stack then print it out to the console window, we then push i onto the stack, and then push 1 onto the stack then add the two popping them both off the stack and store the result of the addition we then perform the i < 10 expression again until it evaluates to false then we return power to the caller.

You might also like...

Comments

About the author

Granville Barnettt United Kingdom

My name is Granville Barnett I have been a programmer now for quite some time mainly focusing on .NET technologies (C#), C++ and general research (algorithms, compilers etc)

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“There's no test like production” - Anon