如何在CLR上学习IL

Tar*_*rik 20 .net clr il

由于这些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
Run Code Online (Sandbox Code Playgroud)

样本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
Run Code Online (Sandbox Code Playgroud)

我知道这些代码在我制作它们之后做了什么:-)但是我想了解更多有关相应IL代码的信息.

这些样本包含类似的IL代码,您可以用问号解释命令吗?这些命令代表什么呢?所以我们可以很容易地记住它们.

  • nop(用于调试 - 无操作)
  • newobj(似乎它在堆中创建新对象)
  • stloc.0?
  • ldloc.0?
  • 回来?
  • ldarg.0?
  • ldstr?
  • stfld?
  • ldc.i4.s?
  • .ctor - 构造函数

理解IL非常重要,因为它揭示了特定编译器如何生成代码并在特定情况下执行操作.

但是,我找不到一个很好的文档,其中包含有关IL的示例.使用C#3.0的CLR是一本好书,但最终它不是IL书,因此它不能解释有关IL的所有内容.

编辑:

我找到了规格,他们告诉我们:感谢@usr.

  • nop(用于调试 - 无操作)
  • newobj - 创建一个新对象
  • stloc.0 - 从堆栈到局部变量的pop值
  • ldloc.0? - 将局部变量加载到堆栈中
  • ret - 从方法返回
  • ldarg.0 - 将参数0加载到堆栈中.
  • ldstr - 加载文字字符串
  • stfld - 存储到对象的字段中
  • ldc.i4.s - 将num作为int32,short form压入堆栈.
  • .ctor - 构造函数

usr*_*usr 9

Microsoft对CLR进行了标准化并发布了这些标准.分区III包含大量有关IL/CIL的信息,适合学习.这是一份很好的文件.

您也可以通过示例学习IL.在C#中编译一些简单的方法,并查看反射器中的IL(它具有IL模式).


Ken*_*rey 9

  • nop - no-op
  • newobj - 创建一个对象并调用其构造函数.
  • stloc.0 - 从堆栈中弹出一个值,并将其存储在第一个局部变量中
  • ldloc.0 - 将第一个局部变量推入堆栈
  • 退回
  • ldarg.0 - 将第一个参数(this在实例方法中)推入堆栈
  • ldstr - 将字符串推入堆栈
  • stfld - 使用堆栈上的数据设置字段.
  • ldc.i4.s - 将指定的数字推送为int.
  • .ctor - 构造函数

我建议您找到关于这些操作码的良好文档来源(维基百科可能是最好的,但是:().System.Reflection.Emit的文档有相当详细的操作码文档.

最重要的是,构建小程序并检查IL输出.这是最好的学习方式.


Dam*_*ver 8

如果您想要简要概述每个操作码,您可能会比检查System.Reflection.Emit命名空间更糟糕.

例如,有一个OpCodes类为每个操作码都有一个静态字段.然后,就其堆叠行为而言,更详细地描述这些中的每一个.例如Ldarg_0:

所述ldarg.0指令将在0索引到计算堆栈的参数.所述ldarg.0指令可用于通过从一个输入参数复制它加载一个值类型或一个原始值压入堆栈.