如何正确反汇编 .NET 代码?

How to disassemble .NET code right?

我正在尝试反汇编我的 C# 代码,然后在汇编语言级别对其进行调试。 假设我们有一个简单的 C# 方法:

var a = 1235;
var b = ++a;
var c = ++b;

Console.WriteLine("test");
Console.ReadKey();

我找到了两种获取汇编代码的不同方法。 第一个是在VS中启动C#代码调试,然后打开Disassemblywindow。这里我们有以下代码。

一切正常,汇编代码非常简单和简短,但问题是此汇编代码的逻辑与 ildasm 生成的 IL 代码的逻辑不同。

所以这是第二种方式。我们可以编译C#代码,使用ildasm从PE文件中获取IL代码,然后使用ilasm生成PE文件。现在我们有以下汇编代码。

如您所见,此汇编代码更像 IL 代码,但它包含的指令更多,也更复杂。

AFAIK C# 在两种情况下都编译为 CIL 代码,然后编译为汇编代码。但似乎是第一种方式它只是编译成汇编代码。

那么问题来了,为什么第一种方法的汇编代码和IL代码不一样呢?为什么第一种方法的汇编代码与第二种方法的汇编代码不同?

JIT 能够重新排序和合并机器指令作为优化,但会尽量避免在 pdb 提供的 sequence points 之间移动效果。编译器通常为每一行代码生成一个序列点,因为您通常一次单步执行一行代码。

虽然 C# 通常会在每行代码中生成多条 IL 指令,但 ilasm 会显式地为每条指令提供信息,因此会生成更多的序列点,从而为 JIT 优化留下更少的空间。