Как изучить IL на CLR

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

Мне не удалось найти такую ​​документацию, как C # Compiler или любую другую, поэтому я думаю, что смогу в значительной степени позаботиться об остальном после того, как выучу эти общие:

Ниже приведены несколько примеров кодов IL, содержащих то, что мне нужно знать:

Пример 1:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       15 (0xf)
  .maxstack  1
  .locals init ([0] class EnumReflection.DerivedClass derivedClass)
  IL_0000:  nop
  IL_0001:  newobj     instance void EnumReflection.DerivedClass::.ctor()
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  callvirt   instance void EnumReflection.DerivedClass::WriteOutput()
  IL_000d:  nop
  IL_000e:  ret
} // end of method Program::Main

Пример 2:

.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // Code size       38 (0x26)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldstr      "Hello"
  IL_0006:  stfld      string EnumReflection.DerivedClass::hello
  IL_000b:  ldarg.0
  IL_000c:  ldstr      "World"
  IL_0011:  stfld      string EnumReflection.DerivedClass::world
  IL_0016:  ldarg.0
  IL_0017:  ldc.i4.s   123
  IL_0019:  stfld      int32 EnumReflection.DerivedClass::age
  IL_001e:  ldarg.0
  IL_001f:  call       instance void EnumReflection.BaseClass::.ctor()
  IL_0024:  nop
  IL_0025:  ret
} // end of method DerivedClass::.ctor

Я знаю, что делают эти коды, так как я их создал :-), однако я хотел бы узнать больше о соответствующем коде IL.

Эти образцы содержат коды IL, например, и не могли бы вы объяснить команду с вопросительными знаками? а также что означают эти команды? Так что мы можем легко их запомнить.

  • nop (для отладки - без операции)
  • newobj (кажется, он создает новый объект в куче)
  • stloc.0?
  • ldloc.0?
  • ret?
  • ldarg.0?
  • ldstr?
  • stfld?
  • ldc.i4.s?
  • .ctor - конструктор

Понимание IL важно, поскольку оно раскрывает, как конкретный компилятор создает коды и действует в конкретных случаях.

Однако мне не удалось найти хороших документов, которые также содержали бы примеры о IL. CLR с C # 3.0 - хорошая книга, однако в конечном итоге это не книга по IL, поэтому она не объясняет все о IL.

РЕДАКТИРОВАТЬ:

Я нашел спецификации, и они говорят следующее: Спасибо @usr.

  • nop (для отладки - без операции)
  • newobj - создать новый объект
  • stloc.0 - передать значение из стека в локальную переменную
  • ldloc.0? - загрузить локальную переменную в стек
  • ret - возврат из метода
  • ldarg.0 - загрузить аргумент 0 в стек.
  • ldstr - загрузить буквальную строку
  • stfld - сохранить в поле объекта
  • ldc.i4.s - помещает число в стек как int32, сокращенная форма.
  • .ctor - конструктор

person Tarik    schedule 21.04.2012    source источник
comment
Загрузите ILSpy и переключите его, чтобы отображать декомпилированный код IL. Вы можете щелкнуть все коды операций, и ILSpy приведет вас к документации Microsoft.   -  person mslot    schedule 25.10.2013
comment
+1 @mslot, спасибо за комментарий о коде IL в ILSpy, я немного использовал ILSpy, но не использовал часть IL. очень полезно щелкнуть код операции и прочитать об этом документацию.   -  person yantaq    schedule 04.06.2015


Ответы (4)


Microsoft стандартизировала среду CLR и опубликовала эти стандарты. Раздел III содержит обширную информацию о IL / CIL и подходит для обучения. Это отличный документ.

Вы также можете изучить IL на собственном примере. Скомпилируйте несколько простых методов на C # и посмотрите на IL в отражателе (у него есть IL-режим).

person usr    schedule 21.04.2012
comment
Это то, что я сделал, но я бы тоже хотел, чтобы эти команды означали. - person Tarik; 21.04.2012
comment
Да, тогда я рекомендую вам изучить спецификацию. Раздел III действительно выглядит неплохо и понятно. - person usr; 21.04.2012
comment
Я нашел то, что действительно ищу, в спецификациях здесь, в этом файле pdf: ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf - person Tarik; 21.04.2012
comment
Ссылка на ECMA-335: ecma-international.org /publications/files/ECMA-ST/ECMA-335.pdf - person SUN Jiangong; 03.08.2018

Есть несколько книг, посвященных Иллинойсе:

Также некоторые книги по реверс-инжинирингу содержат разделы, посвященные IL.

Смотрите также:

person DoctorFoo    schedule 21.04.2012

  • nop - no-op
  • newobj - создать объект и вызвать его конструктор.
  • stloc.0 - извлечь значение из стека и сохранить его в первой локальной переменной
  • ldloc.0 - помещает первую локальную переменную в стек
  • ret - возврат
  • ldarg.0 - помещает первый аргумент (this в методах экземпляра) в стек
  • ldstr - помещает строку в стек
  • stfld - установить поле, используя данные в стеке.
  • ldc.i4.s - передать указанное число как целое.
  • .ctor - конструктор

Я рекомендую вам найти хороший источник документации по этим кодам операций (хотя лучше всего подходит Википедия :(). Документация для System.Reflection.Emit содержит довольно подробную документацию по кодам операций.

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

person Kendall Frey    schedule 21.04.2012

Если вам нужен краткий обзор каждого кода операции, вы можете сделать похуже, чем проверять пространство имен System.Reflection.Emit.

Например, существует класс OpCodes, в котором есть статическое поле для каждый код операции. Затем каждый из них описывается более подробно с точки зрения его поведения в стеке. Например. Ldarg_0:

Инструкция ldarg.0 помещает аргумент с индексом 0 в стек оценки. Инструкцию ldarg.0 можно использовать для загрузки типа значения или примитивного значения в стек путем копирования его из входящего аргумента.

person Damien_The_Unbeliever    schedule 21.04.2012