【发布时间】:2013-01-11 19:24:02
【问题描述】:
我对 MSIL 的工作非常好奇。据我了解,CLR 在编译时将其代码转换为 MSIL,以提供一些优化,这些优化随后由 JIT 转换为机器代码。
例如,如果我们有:
using (TextWriter w = File.CreateText("log.txt"))
{
w.WriteLine("This is line one");
}
它将在 MSIL 中翻译成以下代码:
TextWriter w = File.CreateText("log.txt");
try
{
w.WriteLine("This is line one");
}
finally
{
bool flag = w == null;
if (!flag)
{
w.Dispose();
}
}
我不确定它是否会完全像那样翻译,但肯定会翻译成类似的东西。
关键是,我试图研究 MSIL 优化。 到目前为止,我发现 MSIL 已翻译为对我来说不太可读的 asm 代码。
是否有任何工具可以显示我在 C# 代码甚至伪代码中翻译的 MSIL?
非常感谢参考资料和相关链接。
附言
我使用我们在上面看到的写:
using (TextWriter w = File.CreateText("log.txt"))
{
w.WriteLine("This is line one");
}
并编译它。然后我使用 Reflector 查看代码,我看到了我写的相同代码,而不是看到一些优化。
我使用相同代码的 LINQPad。我发现 MSIL 输出是:
IL_0001: ldstr "log.txt"
IL_0006: call System.IO.File.CreateText
IL_000B: stloc.0 // w
IL_000C: nop
IL_000D: ldloc.0 // w
IL_000E: ldstr "This is line one"
IL_0013: callvirt System.IO.TextWriter.WriteLine
IL_0018: nop
IL_0019: nop
IL_001A: leave.s IL_002C
IL_001C: ldloc.0 // w
IL_001D: ldnull
IL_001E: ceq
IL_0020: stloc.1 // CS$4$0000
IL_0021: ldloc.1 // CS$4$0000
IL_0022: brtrue.s IL_002B
IL_0024: ldloc.0 // w
IL_0025: callvirt System.IDisposable.Dispose
IL_002A: nop
IL_002B: endfinally
从这段代码中,我们看到 System.IDisposable.Dispose 看起来像是优化的一部分。我的意图是查看 C# 代码或伪代码。
【问题讨论】:
-
不清楚您在寻找什么 - Reflector/ILSpy 会将 IL 反编译为 C#,但不确定它如何帮助理解 IL 本身。
-
Reflector 向我展示了我在没有任何优化的情况下编写的相同代码。我写道:使用 (TextWriter w = File.CreateText("log.txt")) { w.WriteLine("这是第一行");这正是他向我展示的内容}
-
下面提到的很多工具实际上都会隐藏优化的事实。他们知道如何识别特定的优化并将反编译的 C# 还原为原始形式。如果你真的想了解 C# 编译器如何优化 IL,请学习 IL。这并不难。只需在网上逐个查看每个命令,几个小时后您就会获得足够的理解来阅读它。您还可以进一步查看 x86 汇编代码。