2012-08-29 11 views
17

Ho il seguente codice in C#Ho capito bene questo codice MSIL?

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

E sto leggendo il codice IL, non ho mai programmato di montaggio prima quindi mi sto chiedendo se quello che fa ogni linea è corretta.

.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 

Ho capito correttamente questo programma?

risposta

11

Praticamente; l'unica cosa che chiarirei è che la casella (IL_0006 e IL_0011) è tipo specifico, quindi sta costruendo esplicitamente una casella di tipo int (non è solo l '"ultimo tipo di valore").

Inoltre, "stack di valutazione vuoto" è fuorviante; non è giusto - ad esempio, consuma un determinato numero di posizioni - non lo "svuota". C'è mai semantica "pila di valutazione vuota" - è sempre "consumare un numero di valori, rimettere un numero di valori" (uno dei quali può essere zero).

+0

Quando n numero di posizioni sono consumate da qualcosa (chiamate ad esempio), solo le prime posizioni sono consumate correttamente? E poi riporta un numero di valori nello stack di valutazione? Immagino sia vero, perché dopo tutto è uno "stack", ma sto solo chiedendo di essere sicuro. – ProgrammerAtWork

+1

Sì. Un'ipotetica operazione che dovrebbe leggere A, B, C, D e produrre Y, Z dovrebbe far scattare 4 voci dallo stack *, calcolare il risultato *, e quindi inserire 2 nuove voci su di esso. (*) non necessariamente in questo ordine, ma le spinte sono sempre l'ultima. – quetzalcoatl

3

Sì, la tua comprensione è quasi del tutto corretta. Una cosa: IL_0010 non viene caricato dallo stack, viene caricato dalla gente del posto. (I locali finiscono nello stack di runtime, ma a livello di IL quelli sono chiamati locali).

+0

L'OP sta descrivendo lo "stack di valutazione" separatamente per i locali in pila, ma sono d'accordo che sarebbe meglio chiamarli solo locali. –

2

E 'corretto, anche se direi un po' con qualche formulazione poco chiara, per esempio:

valutazione put pila posizione 0 nella posizione di stack di 0, lo stack di valutazione viene svuotato

direi

messo ingresso 0a dalla cima della pila in 0a pila-variabile, quindi pop

solo perché penso che una dicitura "meno formale" sia nella maggior parte dei casi semplicemente più chiara da leggere, ma in altri termini, sembra OK.

modifica: hm .. in un ripensamento, direi che non ci sono due cose come "lo stack" e "lo stack di valutazione". C'è solo "lo stack". La parte contrassegnata dell'inizio della parte visibile dello stack, quella con le variabili locali può essere chiamata "slot". Suppongo che con IL, si possa semplicemente dire "variabile locale Nth" e tutto di solito sarebbe chiaro, ma penso che molte variabili diverse possano essere mappate allo stesso slot, quindi potrebbe causare una certa confusione. Inoltre, non vi è alcuna operazione come "svuotare" quando si lavora con lo stack. Solo push/pop con un numero specificato di voci da copiare.