23

由于这些 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 ?
  • 重?
  • ldarg.0 ?
  • ldstr ?
  • stfld?
  • ldc.i4.s ?
  • .ctor - 构造函数

理解 IL 很重要,因为它揭示了特定编译器如何生成代码并在特定情况下采取行动。

但是,我找不到包含有关 IL 示例的好文档。CLR with C# 3.0 是一本好书,但最终它不是一本 IL 书,因此它没有解释有关 IL 的所有内容。

编辑:

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

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

4 回答 4

12

有几本书确实涵盖了 IL:

还有一些关于逆向工程的书籍也有关于 IL 的部分。

也可以看看:

于 2012-04-21T15:37:07.153 回答
10

Microsoft 标准化了 CLR 并发布了这些标准。Part III 包含丰富的 IL/CIL 信息,适合学习。这是一份出色的文件。

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

于 2012-04-21T15:27:21.063 回答
9
  • nop - no-op
  • newobj - create an object and call its constructor.
  • stloc.0 - Pop a value from the stack, and store it in the first local variable
  • ldloc.0 - Push the first local variable onto the stack
  • ret - return
  • ldarg.0 - Push the first argument (this in instance methods) onto the stack
  • ldstr - Push a string onto the stack
  • stfld - set the field, using data on the stack.
  • ldc.i4.s - Push the specified number as an int.
  • .ctor - constructor

I recommend that you find a good source of documentation on these opcodes (Wikipedia may be the best, though :( ). The documentation for System.Reflection.Emit has fairly detailed documentation for opcodes.

And above all, build small programs and examine the IL output. That is the best way to learn.

于 2012-04-21T15:41:41.563 回答
8

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

例如,有一个OpCodes类对每个操作码都有一个静态字段。然后根据其堆栈行为进一步详细描述其中的每一个。例如Ldarg_0

ldarg.0指令将索引为 0 的参数推入计算堆栈ldarg.0指令可用于通过从传入参数复制值类型或原始值将其加载到堆栈中

于 2012-04-21T15:33:27.527 回答