2012-06-19 4 views
2

C#에서 IL (CIL/MSIL 등)로 코드를 변환 중입니다. 조건부에 붙어있는 이유는 다음에 저장할 수 있기를 원하기 때문입니다. 무료 위치입니다. 예 :CIL의 조건부 - 다음 무료 위치를 저장하는 방법은 무엇입니까?

var x = 0; 
if(x > 20) 
x = 1; 

Console.WriteLine(x); 

나는 이것이 내가 올바른 IL 믿고 무엇을 변환하면, 내가 얻을 :

IL_0001: ldc.i4.0  
IL_0002: stloc.0  
IL_0003: ldloc.0  
IL_0004: ldc.i4.s 14 
IL_0006: cgt   
IL_0008: ldc.i4.0  
IL_0009: ceq   
IL_000B: stloc.1  
IL_000C: ldloc.1  
IL_000D: brtrue.s IL_0011 
IL_000F: ldc.i4.1  
IL_0010: stloc.0  
IL_0011: ldloc.0  
IL_0012: call  System.Console.WriteLine 

나는 이것이 올바른 IL 생각하는,하지만 내 예는 매우 정적이다. 당신이 IL 코드에서 볼 경우,이 loc.1에 CEQ의 결과를 저장하는 것은

그리고 이렇게 내 문제입니다 - 컴파일러는 loc.0 이미 (변수를 'X') 찍은보고 다음을 사용 자유로운 위치는 1이었습니다. 제 목표는 주어진 메소드가 조건부 변수 앞에 N 변수를 가질 수있는 곳에서 동적으로 이것을 수행하는 것입니다. 어떻게, C#을에서, op 코드 "가. stloc nextAvailable을"말을 방출하고 등가 하중의 않습니다 :

그래서, 마지막으로, 여기에 내 질문입니까?

+1

이 왜 전혀 경우를 저장할 않습니다 내가 릴리스 모드를 기대

은 (는 사전에 Console.WriteLine(0);까지 전체를 최적화하지한다면) IL 더 같이하기 위해 생성 값의 사용은 다음 명령어에서로드하는 것입니다. – harold

+0

어쨌든 bool을 0과 비교하는 이유는 무엇입니까? IL은'ceq' 명령 @harold – harold

+0

는 그렇지 않은 경우가 동일하면 1을 푸시 또는 0 다음이를 비교 평가 스택의 최상위 두 값을 팝하고. – dlev

답변

2

생성 디버깅하는 동안 심볼보다 큼.

//load the 4-byte integer 0 on to the stack 
IL_0001: ldc.i4.0 
//set the value of local 0 (x) to the previous value on the stack (0) 
IL_0002: stloc.0 
//load up x for the comparison 
IL_0003: ldloc.0 
//load the 4-byte integer 0x14 (20) on to the stack 
IL_0004: ldc.i4.s 14 
//check to see whether two elements back on the stack is greater than one element back on the stack (x > 20), push 1 one back on the stack in the case the first is greater, 0 otherwise 
IL_0005: cgt 
//if 0x14 (20) was the greater (or equal) value, jump over the body of the if block 
IL_0006: brfalse.s IL_0009 
//load the 4-byte integer 1 (1) on to the stack 
IL_0007: ldc.i4.1 
//set the value of local 0 (x) to the previous value on the stack (1) 
IL_0008: stloc.0 
//load the value of local 0 (x) on to the stack 
IL_0009: ldloc.0 
//call Console.WriteLine 
IL_000A: call System.Console.WriteLine 
+1

ILGenerator.DeclareLocal에 문제가 많은되지 않음(), 문제는 멀리 갈 것처럼 보인다. 디버그 기호가 범인이된다는 것은 나에게 결코 발생하지 않았습니다! 감사 – harold

+0

를 병합 할 수 – OnResolve

3

stlocldloc은 오직 일정한 인덱스와 함께 작동합니다. 그러나 그것은 나쁜 것이 아닙니다. 즉, 이미 다른 다음 코드를 내 보낸 경우 다음에 사용할 수있는 인덱스가 있거나 다른 곳에서 코드를 가져온 경우 모든 로컬 인덱스에 대해 최대 값을 가져와 추가해야합니다. 또는 메소드 헤더에서 현지인 수를 읽습니다.

은 또는 당신은 단지 지역을 건너 뛰고 (A brfalse으로) 직접 cgt의 결과를 사용하거나 ble 명령을 사용할 수 있습니다. 그렇다면이 문제는 처음에는 나타나지 않습니다. 의 stloc.1ldloc.1 코드에 존재하지 않지만 유혹하면서 좋은 작은 툴팁을 제공하기 위해 생성 될 수있는 지역을 참조하고 디버그 모드로 컴파일하는 동안 IL보고있는 것 같습니다 나에게