5

考虑这个 C# 片段:

static string input = null;
static string output = null;

static void Main(string[] args)
{
     input = "input";
     output = CallMe(input);
}

public static string CallMe(string input)
{
     output = "output";
     return output;
}

使用 Reflector 反汇编显示:

.method private hidebysig static void Main(string[] args) cil managed
    {
        .entrypoint
        .maxstack 8
        L_0000: nop 
        L_0001: ldstr "input"
        L_0006: stsfld string Reflector_Test.Program::input
        L_000b: ldsfld string Reflector_Test.Program::input
        L_0010: call string Reflector_Test.Program::CallMe(string)
        L_0015: stsfld string Reflector_Test.Program::output
        L_001a: ret 
    }

 .method public hidebysig static string CallMe(string input) cil managed
    {
        .maxstack 1
        .locals init (
            [0] string CS$1$0000)
        L_0000: nop 
        L_0001: ldstr "output"
        L_0006: stsfld string Reflector_Test.Program::output
        L_000b: ldsfld string Reflector_Test.Program::output
        L_0010: stloc.0 
        L_0011: br.s L_0013
        L_0013: ldloc.0 
        L_0014: ret 
    }

让我困惑的是:

L_0010: stloc.0 
L_0011: br.s L_0013
L_0013: ldloc.0 

它存储项目,分支到下一行(无论如何都会执行),然后再次加载它。

是否有一个原因?

4

2 回答 2

7

这只发生在调试中,而不是发布中。我怀疑它可以在调试期间提供帮助。它可能允许您在语句中间放置断点并查看返回值。

请注意,发布版本有更简洁的 IL:

.method private hidebysig static void Main(string[] args) cil managed
{
    .maxstack 8
    L_0000: ldstr "input"
    L_0005: stsfld string Reflector_Test.Program::input
    L_000a: ldsfld string Reflector_Test.Program::input
    L_000f: call string Reflector_Test.Program::CallMe(string)
    L_0014: stsfld string Reflector_Test.Program::output
    L_0019: ret 
}




.method public hidebysig static string CallMe(string input) cil managed
{
    .maxstack 8
    L_0000: ldstr "output"
    L_0005: stsfld string Reflector_Test.Program::output
    L_000a: ldsfld string Reflector_Test.Program::output
    L_000f: ret 
}
于 2009-03-23T21:28:01.417 回答
0

我的猜测是,这是执行 return 语句的样板代码,编译器执行无条件跳转到最后一行,并在执行之前将返回值加载到寄存器中ret。JIT 会更好地优化它,我认为编译器不会费心做任何优化。

于 2009-03-23T21:33:43.760 回答