2015-11-27 47 views
6

Ho il seguente programma per aggiungere i valori. Quando eseguo la chiamata di Aggiungi metodo nel metodo principale e analizzo ILDASM.EXE La dimensione di Maxstack è 2. E dopo la decommentazione, la dimensione maxstack diventa 4.Calcolo del valore di maxstack nel codice IL

Perché nel caso del metodo Main tutte le variabili non vanno nello stack come stack la dimensione rimane solo 2, mentre in caso di chiamata di metodo Aggiungi ogni variabile entra nello stack? È questo il caso in cui il calcolo del metodo principale sta avvenendo uno alla volta in modo tale da richiedere solo due variabili alla volta.

Si prega di cancellare la mia confusione.

static void Main(string[] args) 
{ 
    int x = 2; 
    int y = 3; 
    int a = 4; 
    int b = 5; 
    int c = 6; 

    Console.WriteLine(x + y + a + b + c); 
    Console.WriteLine(Add(10, 20, 30, 40)); 
    Console.ReadLine(); 
} 

static int Add(int x, int y, int z, int a) 
{ 
    return x + y + z + a; 
} 

risposta

7

Ogni inizializzazione delle variabili:

int x = 2; 

richiederà il valore di essere sulla pila: (dimensione dello stack: 1 finora necessarie)

.locals init ([0] int32 x, 
     [1] int32 y, 
     [2] int32 a, 
     [3] int32 b, 
     [4] int32 c) 
IL_0000: ldc.i4.2 // push 2 to the stack 
IL_0001: stloc.0 // load local variable 0 from stack (x = 2) 

Queste operazioni accada in sequenza, pertanto la dimensione massima dello stack richiesta è ancora 1, durante:

E quando si tratta di questo

:

Console.WriteLine(x + y + a + b + c); 

di aggiungere qualsiasi due variabili, è necessario uno stack di 2:

IL_000b: ldloc.0 // copy to stack x, max stack size required is still 1. 
IL_000c: ldloc.1 // copy to stack y, max stack size required is 2 now. 
IL_000d: add  // execute add, will cause the sum x + y to be on stack 
IL_000e: ldloc.2 // copy to stack a 
IL_000f: add  // execute add... (adds a to the result of x + y) 
.... 

Il differenziale IL quando si rimuovere il commento il metodo Add è al di sotto.

Quando si chiama un metodo, è necessario spingere il riferimento istanza nello stack (cioè, se il metodo Add era stato non statici, il puntatore di istanza per il suo tipo di dichiarazione dovrebbe essere inserito nello stack)

Quindi, ogni argomento che deve essere passato al metodo dovrebbe anche essere inserito nello stack.

Pertanto, è il numero di parametri del metodo Add nel tuo caso che definisce la dimensione massima dello stack. Aggiungere un parametro a questo metodo Add, e vedrete che la dimensione massima dello stack salirà a 5:

// method is static so no need to push an instance pointer to the stack 
IL_001a: ldc.i4.s 10 // push to stack 
IL_001c: ldc.i4.s 20 // push to stack 
IL_001e: ldc.i4.s 30 // push to stack 
IL_0020: ldc.i4.s 40 // push to stack 
IL_0022: call  int32 Program::Add(int32, 
             int32, 
             int32, 
             int32) 
IL_0027: call  void [mscorlib]System.Console::WriteLine(int32) 
+0

mi piacerebbe un po 'modificare il fraseggio in alto - non è la * dichiarazione * che utilizza lo spazio di stack, è l'* inizializzazione *. –

+0

@Damien_The_Unbeliever Grazie per la revisione e la correzione. Risolvendolo. –

+0

Quindi è come se IL non fosse generato linea per linea. Voglio dire è come x = 2 prende uno stack spack allora perché non un'altra dichiarazione di valore? E 'come se il compilatore arrivasse a sapere che richiede solo l'aggiunta, quindi saranno 2 gli spazi nello stack. – TBAG