Click here to Skip to main content
15,886,026 members
Please Sign up or sign in to vote.
4.00/5 (2 votes)
See more:
class Program
{
    static void Main(string[] args)
    {
        int first = 10;
        int second = 20;
        int third = 30;
        int forth = 40;
        int fifth = 50;

    }
}

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       18 (0x12)
  .maxstack  1
  .locals init ([0] int32 first,
           [1] int32 second,
           [2] int32 third,
           [3] int32 forth,
           [4] int32 fifth)
  IL_0000:  nop
  IL_0001:  ldc.i4.s   10
  IL_0003:  stloc.0
  IL_0004:  ldc.i4.s   20
  IL_0006:  stloc.1
  IL_0007:  ldc.i4.s   30
  IL_0009:  stloc.2
  IL_000a:  ldc.i4.s   40
  IL_000c:  stloc.3
  IL_000d:  ldc.i4.s   50
  IL_000f:  stloc.s    fifth
  IL_0011:  ret
} // end of method Program::Main

My question is that:
first ,second, third ,forth and fifth variables are allocates as local variables on stack
I think for five variables on stack .maxstack should 5
but .maxstack shows 1 what it means?
Posted
Updated 4-Nov-22 10:38am

Had to look this up, I've written precisely 0 lines of IL, but your question is interesting:
.maxstack is the maximum evaluation stack depth/height, going through the IL, you only have a mamximum of 1 thing on the evaluation stack:

.locals init ([0] int32 first,
           [1] int32 second,
           [2] int32 third,
           [3] int32 forth,
           [4] int32 fifth)

Declares the local variables.

C#
IL_0000:  nop

No-operation?? - Does nothing, so why bother? Like I say, I'm not an expert in this stuff.

IL_0001:  ldc.i4.s   10

Loads the constant 10 into the evaluation stack, stack size= 1.

IL_0003:  stloc.0

Pops the value off the evaluation stack into locals[0]. evaluation stack size=0. Rinse & repeat for the other variables, but the max evaluation stack size remains 1 because each of the 5 values is pushed into stack and popped into the variables individually.

I suppose you could hypothetically re-write like something this (probably won't compile) :

C#
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       18 (0x12)
  .maxstack  5
  .locals init ([0] int32 first,
           [1] int32 second,
           [2] int32 third,
           [3] int32 forth,
           [4] int32 fifth)
  IL_0000:  nop
  IL_0001:  ldc.i4.s   10
  IL_0003:  ldc.i4.s   20
  IL_0004:  ldc.i4.s   30
  IL_0006:  ldc.i4.s   40
  IL_0007:  ldc.i4.s   50 //Stack size 5
  IL_0009:  stloc.4  //Stack size 4
  IL_000a:  stloc.3  //Stack size 3
  IL_000c:  stloc.2  //Stack size 2
  IL_000d:  stloc.1  //Stack size 1
  IL_000f:  stloc.0  //Stack size 0
  IL_0011:  ret
} 


[Edit]
This is in response to the comments by yuthub, it must be read with the caveat that MSIL/CIL is well outside my comfort zone:

There is more than one stack in operation when running. When the const is pushed by the ldc, it is pushed onto the evaluation stack (see here[^] for a good article). When the value is popped from the evaluation stack, in this case, being an int declare in a method, it is placed into a different stack, the stack is the one we'd normally discuss as "The stack" when discussing stack vs heap memory in c# for example. I've updated the earlier part of my question to help clarify.
 
Share this answer
 
v3
Comments
fdiu 25-Oct-12 10:13am    
ldc.i4.s 10
stloc.0
here which stores 10 to variable first
But were is located this first?????
Keith Barrow 25-Oct-12 10:25am    
ldc.i4.s 10 --> Pushes the *constant* (ldc = LoaD Constant? :/) value 10 onto the stack. The constant value is taken from the IL code itself, this line is where the value actually goes from the IL into the executing program itself.
I hope this helps!
fdiu 25-Oct-12 10:32am    
ldc.i4.s 10//will push 10 on stack
stloc.0 //this pops 10 and stores to variable "first"
My question is that :
variable "first" is located on which memory?????
fdiu 25-Oct-12 10:53am    
reply i m waiting
Keith Barrow 25-Oct-12 11:09am    
Sorry but that is just plain rude.
Very late reply here, but that's just because I'd like to add some useful information for those finding this article by googling.
The .maxstack has indeed nothing to do with the .locals, which are part of the method stack and not the evaluation stack.

What we are looking at is the dissasembled result of something built in Debug configuration.

This is why all the local variables in the .locals list have a name and also why you see nop operations. No operation indeed, but it's still kind of an actual step in the program, so as to give the debugger an associated point in code on which one can place a breakpoint.

Release configurations generate a much shorter code, optimized for performance, certainly not containing those nop instructions and also removing the names of the locals.

Note that a lot more optimization is actually done by the JIT though, the next compilation step, executed during runtime.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900