2010-05-21 3 views
6

내가 리플렉터있는 유효한 방법의 IL 코드를 찾고 있었고, 난이로 실행했습니다일리노이 간략한 설명이 짧지 않습니까?

L_00a5: leave.s L_0103 

지침을 접미사 .s로는 INT8 연산을하기로하고, this should be the case with Leave_S as well 충분히 확인된다. 그러나 0x0103은 259이며 이는 int8의 용량을 초과합니다. 방법은 어떻게 든 작동하지만이 방법의 지침을 읽을 때가 INT8해야하는데 있기 때문에,

L_00a5: leave.s L_0003 
입니다

, 3 대신 259를 검색 Mono.Reflection.Disassembler.GetInstructions. 그래서, 제 질문 : 원래의 지시 (leave.s L_0103)는 어떻게 가능합니까? ECMA documentation for that (파티션 III : CIL 명령어 세트)을 살펴본 결과 설명을 찾을 수 없습니다.

아이디어가 있으십니까? 감사.


수정 # 1 : 좋아, 나는 바보입니다. 분기 명령어의 경우 오프셋은 현재 명령어 다음의 명령어 시작부터 계산해야합니다. 나는 설명서를 읽었는데 맹세했지만 어쨌든 그걸 건너 뛰었습니다. 내 방어에서, 나는 오늘 꽤 아파. 한숨.

감사합니다.


편집 # 2 : 그런데, 아무도 관심이 경우, Mono.Reflection.Disassembler.GetInstructions 그것을 변경 지침을 분해 할 때 : (P이 꽤 바보에도 불구하고, 나에게 바보를 호출하지 않는 덕분) 분기 명령에서 피연산자의 의미. 특히 지적했듯이 분기 명령어의 피연산자는 0이 아니라 다음 명령어의 시작 부분에서 오프셋 을 나타냅니다. 그러나 Mono.Reflection은 0에서 시작하는 오프셋을 제공합니다 (이는 내가 혼란 스럽지만 문서의 일부를 건너 뛸 수있는 방법을 설명하지는 않습니다.)

MethodBodyReader.ReadOperand(Instruction instruction)의 추출물 :

switch (instruction.OpCode.OperandType) { 
... 
case OperandType.ShortInlineBrTarget: 
    instruction.Operand = (sbyte) (il.ReadByte() + il.position); 
    break; 
... 
} 

당신이 그것을 볼 수 있듯이이 il.position을 추가하여 다음 명령의 (0부터 시작) 오프셋입니다. 또한, sbyte으로 캐스팅됩니다. 이는 내가 259 대신 3을 얻는 이유입니다. 이것은 버그 (0에서 시작하는 오프셋은 sbyte보다 클 수 있습니다) 인 것으로 보입니다. 나는 Jb Evain (저자)에게 물어보고 다시보고 할 것이다.


수정 # 3 : 그는 아직 대답하지 않은하지만 난 그것을 변경했습니다 :

switch (instruction.OpCode.OperandType) { 
... 
case OperandType.ShortInlineBrTarget: 
    instruction.Operand = ((sbyte) il.ReadByte()) + il.position; 
    break; 
... 
} 

내 문제를 해결 한 것으로 보인다. 나는 sbyte로 캐스팅하여 역방향 점프 (음수 오프셋) 인 경우에 대비하고, intil.position을 추가하면 결과는 int입니다.

나는 그가 당신이 어쨌든 말하는 것을 알려줄 것입니다.


편집 # 4 : 내가 다시보고하는 것을 잊었다. 저자는 이것이 버그라고 확인합니다. 1 바이트로 표현

+0

작은 마이크로 컨트롤러 (Motorola MC68HC11 누구?) 및 상대 분기 지침에 대한 어셈블리 언어에 대한 과거 경험에서 문서에서 "offset"단어를 검색했습니다. 그 이전의 경험이 없었다면 그리워하기 쉽습니다. 또한 BTW 상대 분기는 PC에서 재배치 가능한 코드의 큰 이점입니다. DLL은 서로 다른 메모리 주소에서로드 할 수 있습니다. 동적 로더가이를 수정하지 않아도되기 때문입니다. 물론 .NET에는 JIT가 포함되어 있으므로이 최적화는 실제로 적용되지 않습니다 ... 단지 공간을 절약하기 위해 완료되었습니다. –

답변

3

타겟 명령이

0xA5가 0x103 127 바이트 내에 현재 명령어 다음 명령어의 시작으로부터 오프셋 체결했다. 그러나 leave.s은 0xA5에서 0x03까지 도달 할 수 없습니다.