2012-08-29 16 views
17

Tengo el siguiente código en C#¿Entiendo este código MSIL correctamente?

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

Y estoy leyendo el código IL, nunca he programado el montaje antes, así que estoy preguntando si lo que hace cada línea es la correcta.

.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 

¿Entiendo este programa correctamente?

Respuesta

11

Bastante; Lo único que aclararía es que el cuadro (IL_0006 y IL_0011) es tipo específico, por lo que está construyendo explícitamente un cuadro del tipo int (no es solo el "último tipo de valor").

Además, la "pila de evaluación vacía" es engañosa; eso no es del todo correcto, por ejemplo, call consume un número dado de posiciones - no lo "vacía". No hay nunca una semántica de "pila de evaluación vacía" - siempre es "consumir una cantidad de valores, devolver una cantidad de valores" (cualquiera de los cuales puede ser cero).

+0

Cuando n cantidad de posiciones son consumidas por algo (llamada por ejemplo), solo se consumen las primeras posiciones ¿verdad? ¿Y luego vuelve a poner una cantidad de valores en la pila de evaluación? Supongo que esto es cierto, porque es una 'pila' después de todo, pero solo estoy preguntando para estar seguro. – ProgrammerAtWork

+1

Sí. Una operación hipotética que leería A, B, C, D y produciría Y, Z sacaría 4 entradas de la pila *, calcularía el resultado * y luego insertaría 2 nuevas entradas en ella. (*) no necesariamente en ese orden, pero los empujones son siempre los últimos. – quetzalcoatl

3

Sí, su comprensión es casi del todo correcta. Una cosa: IL_0010 no carga desde la pila, se carga desde los locales. (Los lugareños terminan en la pila de tiempo de ejecución, pero en el nivel de IL se llaman locales).

+0

El OP está describiendo la "pila de evaluación" por separado para los lugareños en la pila, pero estoy de acuerdo en que sería mejor simplemente llamarlos lugareños. –

2

Es correcto, aunque yo diría un poco con una redacción poco clara, por ejemplo:

Evaluación puesto de apilamiento de 0 a la posición de la pila 0, la pila de evaluación se vacía

diría

puso entrada 0th desde la parte superior de la pila en la pila 0 ª-variable, entonces pop

simplemente porque creo que una redacción "menos formal" es en la mayoría de las ocasiones simplemente más clara de leer, pero de lo contrario, parece estar bien.

editar: hm .. en un último momento, diría que no hay dos cosas como "la pila" y "la pila de evaluación". Solo hay "la pila". La parte marcada del inicio de la parte visible de la pila, esa parte con variables locales se puede llamar "ranuras". Supongo que con IL, se podría decir "variable local Nth" y todo estaría claro, pero creo que varias variables diferentes pueden asignarse al mismo intervalo, por lo que puede causar cierta confusión. Además, no hay ninguna operación como "vaciar" cuando trabajas con la pila. Solo push/pop con un número explícitamente especificado de entradas para copiar.