CIL中的nop的意义是什么 [英] What is the point of nop in CIL
问题描述
所以我用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屋!