IL简短说明不短?

时间:2010-05-21 12:17:16

标签: c# .net reflection reflection.emit il

我正在查看使用Reflector的有效方法的IL代码,我遇到了这个问题:

L_00a5: leave.s L_0103

带有后缀.s的说明应该采用int8操作数,并且确定this should be the case with Leave_S as well。但是,0x0103是259,超过了int8的容量。该方法以某种方式工作,但当我阅读方法Mono.Reflection.Disassembler.GetInstructions的指令时,它检索

L_00a5: leave.s L_0003

即3而不是259,因为它应该是一个int8。那么,我的问题是:原始指令(leave.s L_0103)如何可能?我查看了ECMA documentation for that分区III:CIL指令集),我找不到任何可以解释它的内容。

有什么想法吗?感谢。


编辑#1:好的,我是个白痴。在分支指令的情况下,必须从当前指令之后的指令开始计算偏移量。我发誓我阅读了文档,但不知怎的,我设法跳过了。在我的辩护中,我今天病得很重。叹息。

谢谢。 (并且感谢你没有称我为白痴,尽管这非常愚蠢:P)


编辑#2:顺便说一句,如果有人感兴趣,当Mono.Reflection.Disassembler.GetInstructions反汇编指令时,它会更改分支指令中操作数的含义。特别是,正如已经指出的那样,分支指令的操作数表示从下一条指令开始的偏移,而不是从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,这是我得到3而不是259的原因。这似乎是一个错误(从0开始的偏移可能大于sbyte)。我会问Jb Evain(作者)并报告回来。


编辑#3:他尚未回答,但我已将其更改为:

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

似乎解决了我的问题。我转向sbyte以获得正确的符号,以防它是向后跳转(负偏移),然后当我添加il.position(这是int)时,结果为{ {1}}。

无论如何,我会告诉你他的意思。


编辑#4 :我忘了回报。作者证实这是一个错误。

1 个答案:

答案 0 :(得分:3)

  

目标指令,表示为当前指令之后的指令开头的1字节有符号偏移

0xA5在0x103的127个字节内。然而,leave.s无法从0xA5到达0x03。