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

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

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

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

Ниже приведены некоторые примеры 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. CLR с С# 3.0 - хорошая книга, но в конечном итоге это не книга IL, поэтому она не объясняет все об ИЛ.

EDIT:

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

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

Ответ 1

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

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

Ответ 2

Есть несколько книг, которые охватывают IL:

Также некоторые книги по обратной инженерии имеют разделы на ИЛ.

См. также:

Ответ 3

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

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

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

Ответ 4

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

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

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