3

A second attempt at phrasing this:

I am currently taking baby steps in getting to grips with some MSIL.

I keep hearing the 'Evaluation Stack' talked about as the stack that operations are pushed and poped as they are loaded, used etc.

So, given the following code:

public class Program
{
    public static void Main()
    {
        var message = GetMessage();

        Console.WriteLine(message);
    }

    public static string GetMessage()
    {
        return "Hello World!";
    }
}

The MSIL looks as so:

.class public auto ansi beforefieldinit Program
    extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor () cil managed 
    {
        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    }

    .method public hidebysig static string GetMessage () cil managed 
    {
        .locals init (
            [0] string V_0
        )

        IL_0000: nop
        IL_0001: ldstr "Hello World!"
        IL_0006: stloc.0
        IL_0007: br.s IL_0009

        IL_0009: ldloc.0
        IL_000a: ret
    }

    .method public hidebysig static void Main () cil managed 
    {
        .entrypoint
        .locals init (
            [0] string V_0
        )

        IL_0000: nop
        IL_0001: call string Program::GetMessage()
        IL_0006: stloc.0
        IL_0007: ldloc.0
        IL_0008: call void [mscorlib]System.Console::WriteLine(string)
        IL_000d: nop
        IL_000e: ret
    }
}

I think that the lines which start with IL_xxxx are the evaluation stack (please correct me if I am wrong). So the line call string Program::GetMessage() is the line that calls another method.

So, I guess that question I am asking is this:

  1. Is each line starting with IL_0000 a 'new' evaluation stack?
  2. Is the call stack I see at runtime a joining\concatenation\filtering of this IL?
BanksySan
  • 27,362
  • 33
  • 117
  • 216
  • @CodeCaster I thought the `call` opcode called methods. At least, that's what's been implied by what I've read so far. – BanksySan Mar 12 '15 at 21:58
  • It maybe helps if you cite relevant sections of the CLI specification, so the reader can understand your train of thought. – CodeCaster Mar 12 '15 at 22:01
  • @CodeCaster I'm just learning about it now, now videos and blogs. I'm at the MSIL 'Hello World' stage, hence it being quite probably that my question isn't making sense to anyone with experience. I'll re-phrase it and try again. – BanksySan Mar 12 '15 at 22:03
  • Fairly important to keep in mind that the eval stack is an *abstraction*. It serves the virtual machine that a compiler generates CIL for. It has absolutely nothing to do with the *real* code that the processor executes. The job of the jitter, the most important thing it does is to get rid of the eval stack because it is entirely too inefficient. But yes, the CIL for every method has a virtual eval stack that starts from scratch. And the stack trace you see in debugger is, roughly, a stack of stacks. – Hans Passant Mar 12 '15 at 22:27

2 Answers2

6

I think that the lines which start with IL_xxxx are the evaluation stack

Is each line starting with IL_0000 a 'new' evaluation stack?

No. There is one evaluation stack per method. Think of it as a Stack<object>. IL instructions operate on that stack by pushing and popping items. The MSDN documentation calls out the stack behavior for each IL opcode precisely.

The call stack has nothing to do with the evaluation stack. The call stack is what the Call Stack Visual Studio window shows you.

Is the call stack I see at runtime a joining\concatenation\filtering of this IL?

No. There is no relationship.

I feel that your thinking of the evaluation stack is too complicated. It is quite an easy concept. As long as you have something complicated in mind you have not grasped it. I'm not sure where exactly the misunderstanding lies, though.

Note, that the evaulation stack is a logical concept used to define the meaning of IL programs. It does not exist at runtime anymore in contrast to the call stack which (barring inlining) does exist.

Community
  • 1
  • 1
usr
  • 168,620
  • 35
  • 240
  • 369
  • Is there a situation where there'd be a line, starting with `IL_0000` which wouldn't be the start of a new method? – BanksySan Mar 13 '15 at 13:57
  • Yes, these are arbitrary labels. They are not part of IL and have no meaning except as a branch target. You can "label lines" however you like. They also bear no relationship to the stacks at all. – usr Mar 13 '15 at 15:12
  • 1
    "As long as you have something complicated in mind you have not grasped it" - gold saying! – zzfima Jul 29 '21 at 08:13
1

In CIL context, which is abstract (compared to the physical code executed on the processor).

I would say that the Call stack is stack of the called methods "Method state" and the Evaluation Stack is contained in each "Method state" and contains "execution data". Data on which we operate using the instruction like: Pop / Ldarg...

Each method - "Method state" - has its own local Evaluation Stack.

Ref: ECMA-335_6th_edition_june_2012.pdf - page: 108

OpCodes.Ldarg

Mike Dev
  • 315
  • 1
  • 10