Question

I have the following code in C#

// test.Program
private static void Main()
{
    int x = 5;
    int y = 100;
    Console.WriteLine(y + ", " + x);
}

And I'm reading the IL code, I've never programmed assembly before so I'm asking if what I each line does is correct.

.method private hidebysig static 
    void Main () cil managed 
{
    // Method begins at RVA 0x2058
    // Code size 33 (0x21)
    .maxstack 3 // maximum stack in this method is 3
    .entrypoint // method is initial entry point
    .locals init ( // reserves memory for x and y variables
        [0] int32 x, // x variable is reserved on position 0 of the stack
        [1] int32 y  // y variable is reserved on position 1 of the stack
    )
    IL_0000: ldc.i4.5     // integer of 4 bytes in size and the value of 5 is loaded onto the evaluation stack position 0
    IL_0001: stloc.0      // put evaluation stack position 0 into the stack position 0, the evaluation stack is emptied
    IL_0002: ldc.i4.s 100 // integer of 4 bytes in size and the value of 100 is loaded onto the evaluation stack position 0
    IL_0004: stloc.1      // put evaluation stack position 0 onto the stack position 1, the evaluation stack is emptied
    IL_0005: ldloc.1      // load stack position 1 into the evaluation stack position 0
    IL_0006: box [mscorlib]System.Int32 // box last valuetype placed on evaluation stack, replace valuetype with reference on evaluation stack position 0, do not empty stack
    IL_000b: ldstr ", "   // put reference to string on evaluation stack position 1
    IL_0010: ldloc.0      // load stack position 0 into the evaluation stack position 2
    IL_0011: box [mscorlib]System.Int32 // box last valuetype placed on evaluation stack, replace valuetype with reference on evaluation stack position 0, do not empty stack
    IL_0016: call string [mscorlib]System.String::Concat(object, object, object) // call Concat, pass values on evaluation stack, empty evaluation stack, put result of concat on evaluationstack
    IL_001b: call void [mscorlib]System.Console::WriteLine(string) // pass first value in evaluation stack
    IL_0020: ret         // return
} // end of method Program::Main

Do I understand this program correctly?

Was it helpful?

Solution

Pretty much; only thing I'd clarify is that the box (IL_0006 and IL_0011) is type specific, so it is explicitly constructing a box of type int (it isn't just the "last valuetype").

Also, "empty evaluation stack" is misleading; that isn't quite right - for example, call consumes a given number of positions - it doesn't "empty" it. There is never an "empty evaluation stack" semantic - it is always "consume a number of values, put back a number of values" (either of which may be zero).

OTHER TIPS

Yes, your understanding is almost entirely correct. One thing: IL_0010 does not load from the stack, it loads from the locals. (Locals end up on the runtime stack but at the IL level those are called locals).

It is correct, although I'd argue a bit with some unclear wording, for example:

put evaluation stack position 0 into the stack position 0, the evaluation stack is emptied

I'd say

put 0th entry from the top of the stack into stack-variable 0th, then pop

just because I think a 'less-formal' wording is in most of the times simply clearer to read, but othwerwise, it seems OK.

edit: hm.. in an afterthought, I'd say that there are no two things like "the stack" and "the evaluation stack". There's only "the stack". The marked part of the start of visible part of stack, that one with local variables may be called "slots". I'd suppose that with IL, you could just say "local variable Nth" and everything usually would be clear, but I think that several different variables may be mapped to the same slot, so it may cause some confusion. Also, there is no operation like "emptying" when you work with the stack. Only push/pop with a explicitely specified number of entries to be copied.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top