Подтвердить что ты не робот

Я правильно понимаю этот код MSIL?

У меня есть следующий код в С#

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

И я читаю код IL, я никогда не программировал сборку, поэтому я спрашиваю, правильно ли я выполняю каждую строку.

.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

Я правильно понял эту программу?

4b9b3361

Ответ 1

В значительной степени; Единственное, что я уточнил, это то, что ящик (IL_0006 и IL_0011) имеет тип, поэтому он явно создает поле типа int (это не просто "последний тип знака" ).

Кроме того, "пустой стек оценки" вводит в заблуждение; это не совсем правильно - например, call потребляет определенное количество позиций - оно не "пуст". Существует никогда семантик "пустой тестовой стеки" - он всегда "потребляет несколько значений, возвращает несколько значений" (любой из которых может быть равен нулю).

Ответ 2

Да, ваше понимание почти полностью верно. Одно: IL_0010 не загружается из стека, он загружается из локальных сетей. (Локали заканчиваются в стеке времени выполнения, но на уровне IL они называются locals).

Ответ 3

Это правильно, хотя я бы немного спорил с некоторыми неясными формулировками, например:

положите оценку позиции стека 0 в позицию стека 0, стек оценки опустел

Я бы сказал

введите 0-ю запись из верхней части стека в стек-переменную 0-го, затем нажмите

только потому, что я думаю, что "менее формальная" формулировка в большинстве случаев просто понятна для чтения, но иногда кажется, что это нормально.

edit: hm.. в запоздалой мысли, я бы сказал, что нет двух таких вещей, как "стек" и "стек оценки". Там только "стек". Отмеченная часть начала видимой части стека, которая с локальными переменными может быть названа "слотами". Я бы предположил, что с помощью IL вы могли бы просто сказать "локальная переменная Nth", и все обычно было бы ясным, но я думаю, что несколько разных переменных могут быть сопоставлены с одним слотом, поэтому это может вызвать некоторую путаницу. Кроме того, при работе со стеком не работает операция "опорожнение". Только push/pop с явно указанным количеством записей, которые нужно скопировать.