所以我在C#中编写了以下代码.
class Test
{
int a;
System.IO.StreamReader reader;
public Test()
{
a = 5;
reader = new System.IO.StreamReader(String.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
IL中类的构造函数看起来像这样
.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
Run Code Online (Sandbox Code Playgroud)
有3个nop命令.(据我所知,这表示无操作).这些命令的需要是什么.我的意思是,如果根本没有命令,那会有什么不同nop
Han*_*ant 19
它们在为程序写入.pdb文件时由C#编译器使用.其中包含调试信息,其中包含代码的文件+行号信息.调试器使用它来查找需要注入INT 3指令的机器代码,以便在设置断点时让程序停止执行.抖动为MSIL中的每个Opcodes.Nop发出NOP机器代码指令.
在设置断点时使用第一个nop public Test().请注意,它是在基础构造函数调用之后注入的,以便此变量在Auto/Locals/Watch调试窗口中变为有效.
在第一个{花括号上设置断点时使用第二个nop.该行根本不生成任何代码,因此非常需要伪造的MSIL指令.
第三个nop的相同故事,为最后一个大括号生成.当您在该断点上设置断点时,您可以检查方法返回值(如果有).在Debug + Windows + Registers窗口中间接可见.在VS2013中得到改进.
因此,这只是帮助调试程序,它们使断点可以预测.在构建程序的Release配置时,不会生成这些NOP .C#项目具有Debug和Release配置的一个重要原因.你仍然可以调试一个Release版本,但这是一个相当混乱的体验,让你怀疑你的理智:)
| 归档时间: |
|
| 查看次数: |
1175 次 |
| 最近记录: |