Краткие команды IL не коротки?

Я смотрел на код IL действительного метода с Отражателем, и я столкнулся с этим:

L_00a5: leave.s L_0103

Инструкции с суффиксом .s как предполагается, берут int8 операнд, и конечно же это должно иметь место с Leave_S также. Однако 0x0103 259, который превышает способность int8. Метод так или иначе работает, но когда я прочитал инструкции с методом Mono.Reflection.Disassembler.GetInstructions это получает

L_00a5: leave.s L_0003

то есть, 3 вместо 259, потому что это, как предполагается, int8. Так, мой вопрос: как исходная инструкция (leave.s L_0103) возможный? Я посмотрел на документацию ECMA для того (Раздел 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) результат int.

Я сообщу то, что он говорит так или иначе.


РЕДАКТИРОВАНИЕ № 4: Я забыл сообщать. Автор подтверждает, что это было ошибкой.

6
задан Alix 8 June 2010 в 16:59
поделиться

1 ответ

целевая инструкция, представленная как 1-байтовое смещение со знаком от начала инструкции, следующей за текущей инструкцией

0xA5 находится в пределах 127 байтов от 0x103. Однако нет возможности для leave.s перейти от 0xA5 до 0x03.

3
ответ дан 17 December 2019 в 18:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: