如何在CLR上学习IL

时间:2012-04-21 15:22:25

标签: .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

示例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的例子的好文档。使用C#3.0的CLR是一本好书,但最终它不是IL书,因此它不能解释有关IL的所有内容。

修改

我找到了规格并告诉他们:感谢@usr。

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

4 个答案:

答案 0 :(得分:12)

答案 1 :(得分:9)

Microsoft standardized the CLR and published those standards。分区III包含大量有关IL / CIL的信息,适合学习。这是一份很好的文件。

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

答案 2 :(得分:9)

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

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

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

答案 3 :(得分:8)

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

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

  

ldarg.0 指令将索引为0的参数推送到评估堆栈。 ldarg.0 指令可用于通过从传入参数复制值类型或原始值到堆栈中。