CIL中的nop的意义是什么 [英] What is the point of nop in CIL

查看:113
本文介绍了CIL中的nop的意义是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我用C#编写了以下代码。

So I wrote the following code in C#.

class Test
{
    int a;
    System.IO.StreamReader reader;

    public Test()
    {
        a = 5;
        reader = new System.IO.StreamReader(String.Empty);
    }
}

IL中类的构造函数如下所示

And the constructor of the class in IL looks like this

.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // Code size       33 (0x21)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  nop
  IL_0007:  nop
  IL_0008:  ldarg.0
  IL_0009:  ldc.i4.5
  IL_000a:  stfld      int32 Test2.Test::a
  IL_000f:  ldarg.0
  IL_0010:  ldsfld     string [mscorlib]System.String::Empty
  IL_0015:  newobj     instance void [mscorlib]System.IO.StreamReader::.ctor(string)
  IL_001a:  stfld      class [mscorlib]System.IO.StreamReader Test2.Test::reader
  IL_001f:  nop
  IL_0020:  ret
} // end of method Test::.ctor

共有3条 nop 命令。 (据我所知,它代表不进行任何操作)。这些命令有什么需要。我的意思是,如果根本没有命令而不是 nop

There are 3 nop commands. (Which as I know stands for no operation). What is the need of those commands. I mean what would be the difference if there was no command at all instead of nop

推荐答案

当C#编译器为您的程序编写.pdb文件时,它们将被使用。其中包含调试信息,其中包括代码的文件+行号信息。调试器使用它来查找需要在其上注入 INT 3 指令以使程序在设置断点时停止执行的机器代码。抖动会为每个操作码发出一条NOP机器码指令。MSIL中的Nop。

They are used by the C# compiler when it writes the .pdb file for your program. Which contains debugging info, which includes file+line number info for your code. The debugger uses this to find the machine code where it needs to inject an INT 3 instruction to get the program to stop executing when you set a breakpoint. The jitter emits a NOP machine code instruction for each Opcodes.Nop in the MSIL.

当您在 public上设置断点时,将使用第一个nop。 Test()。请注意,它是在基本构造函数调用后 注入的,因此 this 变量在自动/本地/监视调试窗口中有效。

The first nop is used when you set a breakpoint on public Test(). Note that it is injected after the base constructor call so that the this variable becomes valid in the Auto/Locals/Watch debugging windows.

在第一个{花括号上设置一个断点时,使用第二个nop。该行根本不生成任何代码,因此非常需要伪造的MSIL指令。

The second nop is used when you set a breakpoint on the first { curly brace. That line generates no code at all so there's a hard need for a fake MSIL instruction.

第三个nop的情况与此相同,最后一个}花括号生成了。在该断点上设置断点时,可以检查方法的返回值(如果有)。在调试+ Windows +注册窗口中间接可见。在VS2013中进行了改进。

Same story for the third nop, generated for the last } curly brace. When you set a breakpoint on that one then you can inspect the method return value (if any). Visible indirectly in the Debug + Windows + Registers window. Improved in VS2013.

因此,这仅有助于调试程序,它们使断点可预期地起作用。当您构建程序的Release配置时, not 不会生成那些NOP。 C#项目具有Debug和Release配置的一个重要原因。您仍然可以调试Release版本,但这是一种令人困惑的体验,使您怀疑自己的理智:)

So this just aids in debugging your program, they make breakpoints act predictably. Those NOPs are not generated when you build the Release configuration of your program. One big reason why a C# project has a Debug and a Release configuration. You can still debug a Release build, it is however a pretty confounding experience that makes you doubt your sanity :)

这篇关于CIL中的nop的意义是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆