Почему он загружает как ldarg.0, так и ldarg.1, когда есть только 1 аргумент? - PullRequest
1 голос
/ 16 июня 2019

Я совершенно не понимаю, как работает этот ассемблерный код. Я пытался найти ответы, но ничего не смог найти. Я думаю, что ldarg.0 загружен из-за void экземпляра, но я не уверен, почему он загружает ldarg.1.

Буду очень признателен, если кто-нибудь сможет объяснить, что происходит.

.method public hidebysig specialname instance void set_phase(string value)
  {
    .maxstack 3
    .locals init (bool V0)
nop
ldarg.1
ldarg.0
ldfld    string KGER.Generate::_phase
call     bool [mscorlib]System.String::op_Inequality(string, string)
ldc.i4.0
ceq
stloc.0
ldloc.0
brtrue.s loc_4E8

Заранее спасибо!

1 Ответ

0 голосов
/ 16 июня 2019

Однако ваш код не является полным: часть выполняет следующие действия:

Это подпись метода. отсюда вы выводите две важные вещи: во-первых, это метод instance. Это означает, что первый неявный аргумент содержит this. Вторая важная вещь - это подпись, состоящая из одного аргумента типа string: это будет arg1, поскольку arg0 неявно используется для хранения this.

.method public hidebysig specialname instance void set_phase(string value)
  {
    .maxstack 3
    .locals init (bool V0)

вычислительно, это ничего не делает. среди прочего, nop инструкции могут использоваться отладчиками для безопасного размещения точек останова

nop

это загружает arg1 в стек. Стек содержит ( значение поля с именем value ) ldarg.1

затем загружает аргумент this и немедленно использует его для загрузки поля KGER.Generate::_phase. стек теперь содержит (значение содержимое поля _phase )

ldarg.0
ldfld    string KGER.Generate::_phase

это вызывает оператор op_Inequality класса String, который является статическим методом. стек теперь содержит ( результат сравнения )

call     bool [mscorlib]System.String::op_Inequality(string, string)

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

ldc.i4.0

это сравнивает два значения в стек и помещает результат как логическое значение в стек Ceq

хранит результат сравнения с локальной переменной (первой) stloc.0

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

ldloc.0

это переходит к расположению loc_4E8, когда значение равно true (т.е. 1), что означает, что если две строки равны, код будет прыгать.

brtrue.s loc_4E8
...