문제

이 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;
}

리플렉터를 사용하여 해부하는 것은 다음과 같습니다.

.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 

항목을 저장하고 다음 줄에 분기를 저장 한 다음 (어쨌든 실행되었을 것입니다) 다시로드합니다.

이에 대한 이유가 있습니까?

도움이 되었습니까?

해결책

이것은 릴리스가 아닌 디버그에서만 발생합니다. 디버깅 중에 도움이 될 것 같습니다. 아마도 문장 중간 명령문을 chuck하고 반환 값을 볼 수 있습니다.

릴리스 버전에는 훨씬 더 간결한 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 
}

다른 팁

내 생각에 이것은 반환 명령문을 실행하기위한 보일러 플레이트 코드이며, 컴파일러는 마지막 줄로의 무조건 점프를 실행하고 리턴 값을 레지스터에로드하기 전에 레지스터에로드합니다. ret. JIT는 더 잘 최적화 할 것입니다. 컴파일러는 어떤 최적화를 귀찮게하지 않는다고 생각합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top