Понимание CIL и работы ldelem.ref - PullRequest
0 голосов
/ 28 декабря 2018

Я хотел бы объяснить, что делает ldelem.ref.Пока у меня есть, что он загружает элемент с индексом на вершину стека как O.

Что такое индекс?И я думаю, что тип O означает, что тип объекта останется таким, каким он был, например, если это была строка, она останется строкой.

У меня есть пример ниже некоторого кода, который яЯ работаю над, и я был бы очень признателен за понимание.Я прокомментировал то, что я считаю, я знаю.Так что в этом случае

.locals init (
    string V_0,
    bool V_1,
    string V_2,
    bool V_3,
    string V_4,
    string V_5,
    string V_6)              // Declared 6 variables

.try 
{
    IL_0000:  nop
    IL_0001:  nop                   // Does nothing - Debug build
    IL_0002:  ldarg.0               // Loads Argument 0 into memory/stack
    IL_0003:  ldc.i4.0              // Push Constant Value 0 into memory [Possibly from a variable]
    IL_0004:  ldelem.ref            // Loads element at index onto the top of the stack as an O
    IL_0005:  stloc.0               // Pop value from stack into local Variable 0
    IL_0006:  ldloc.0               // Load local variable 0 onto stack
    IL_0007:  ldstr      "del"      // Loads string "del" in to top of stack
    IL_000c:  call       bool [mscorlib]System.String::op_Equality(string, string)  // Compares strings to see if they are equal
    IL_0011:  stloc.1               // Pop value from stack into local variable 1
    IL_0012:  ldloc.1               // Load local variable 1 onto the stack
    IL_0013:  brfalse.s  IL_004e    // If variable 1 is true keep going else jump to IL_004e

Что здесь делает ldelem.ref?op_Equality сравнивает строку "del" с содержимым переменной 0?Я предполагаю, что после завершения вызова логическое значение операции сохраняется в верхней части стека, и stloc.1 выводит логическое значение и сохраняет его в переменной 1, затем ldloc.1 загружает эту переменную встек и brfalse.s проверяет значение Bool, и если false "переходит" к IL_004e, так ли это?

1 Ответ

0 голосов
/ 28 декабря 2018

ldelem.ref помещает ссылку на элемент массива в стек.Это означает, что он делает его копию, а не фактическую сохраненную ссылку.Может быть полезно прочитать документацию System.Reflection.Emit , чтобы понять больше.

Еще одна вещь, которая может быть полезна для понимания, состоит в том, что каждая инструкция MSIL требует N значений из стека, гдеN определяется конкретной используемой инструкцией (среди прочего).Затем это можно использовать для умственной группировки вещей для более легкого понимания.

IL_0002:  ldarg.0               
IL_0003:  ldc.i4.0              
IL_0004:  ldelem.ref 

ldelem.ref требует, чтобы в стеке имелся следующий порядок: ссылка на массив, индекс в этом массиве.Это вытолкнет эти значения, а затем поместит ссылку в стек.Стек теперь содержит одну вещь.

IL_0005:  stloc.0 

Единственное значение в стеке теперь извлекается и помещается в локальное хранилище.Стек пуст.

IL_0006:  ldloc.0               
IL_0007:  ldstr      "del"      
IL_000c:  call       bool [mscorlib]System.String::op_Equality(string, string)  

Команда вызова вытолкнет столько элементов в стеке, сколько и параметров (включая экземпляр, если вызванный метод является методом экземпляра).В этом случае ему нужны два строковых параметра, и они будут извлекать как содержимое локальной переменной, так и буквенную строку «del».Статический метод op_Equality возвращает тип bool, поэтому он будет помещен в стек.Стек теперь содержит одну вещь.

IL_0011:  stloc.1               

Единственное значение в стеке теперь извлекается и помещается в локальное хранилище.Стек пуст.

IL_0012:  ldloc.1               
IL_0013:  brfalse.s  IL_004e    

Затем загружается значение и применяется логика ветвления.

В C # MSIL выполняет нечто эквивалентное следующему:

if (array[0] == "del")

Все в MSIL - это балансирование.Из-за того, что это отладочная сборка, может быть больше nop-инструкций и больше использования локальных компьютеров, чем оптимизированной сборки (что хорошо для вас, потому что вы можете немного легче следить за вещами).

...