see remarks cref c# .net cil il ilasm

c# - remarks - ¿Entiendo este código MSIL correctamente?



remarks c# documentation (3)

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

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

Tengo el siguiente código en C #

// 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 ensamblaje antes, así que estoy preguntando si lo que hago en cada línea es correcto.

.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?


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

ponga la posición de pila de evaluación 0 en la posición de pila 0, la pila de evaluación se vacía

Yo diría que

ponga la 0ª entrada de la parte superior de la pila en la variable de pila 0ª, luego salte

solo porque creo que una redacción "menos formal" es en la mayoría de los casos simplemente más clara de leer, pero en otras palabras, parece estar bien.

edit: hm .. en una ocurrencia tardía, diría que no hay dos cosas como "la pila" y "la pila de evaluación". Sólo hay "la pila". La parte marcada del inicio de la parte visible de la pila, aquella con variables locales, puede denominarse "ranuras". Supongo que con IL, solo podría decir "variable local Nth" y, por lo general, todo quedaría claro, pero creo que se pueden asignar varias variables diferentes a la misma ranura, por lo que puede causar cierta confusión. Además, no hay ninguna operación como "vaciar" cuando trabajas con la pila. Solo presione / salte con un número explícito de entradas para copiar.


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