Определить байт, появляющийся в отладке после закодированного вручную дальнего вызова

Мне не удалось заставить MASM принять инструкцию дальнего вызова, написанную как call 0f000h:1260h, вероятно, из-за проблем, поднятых в этот вопрос.

Вместо того, чтобы возиться с загадочными директивами MASM, я решил вручную закодировать его в свою программу, используя БД, вот так:

pushf                      ;IRET will be executed, push flags.
db 9ah,60h,12h,0,0f0h      ;call location f000:1260.
                           ;Location pointed to by int 1c (System timer tick)
                           ;BIOS defaults it to a dummy IRET

Просматривая программу с помощью DEBUG.COM, я заметил, что "DB FE" появляется после выполнения инструкции call. Однако этого не происходит при выполнении int 1ch. В чем разница между этими двумя способами перехода к местоположению f000:1260?

введите здесь описание изображения

Я предположил, что DEBUG не распознает 0xfe (вместе со следующими байтами) как допустимый код операции. Я сбросил адрес f000:1260, чтобы посмотреть, какие байты там были.

введите здесь описание изображения

Байт 0xfe действительно присутствует вместе с некоторыми другими байтами. Я знаю, что 0xcf сам по себе является кодом операции для IRET (это все, что я ожидал найти), так что же это за другие байты?

Вот запись IVT для int 1ch по адресу 0000:0070.

введите здесь описание изображения

ОБНОВЛЕНИЕ

Как заявил Майкл Петч в своем ответе, странные байты составляют механизм обратного вызова в DOSBox. Мне было любопытно посмотреть, что произойдет, если я попытаюсь выполнить этот обратный вызов в своей основной программе.

Выполнение:

xor ah, ah                 ;select set video mode function
mov al, 13h                ;320x200 256 colors
db 0feh,38h,18h,00h        ;set video mode DOSBox callback.
                           ;Nothing pushed to stack.

Кажется, это точно так же, как выполнение:

xor ah, ah                 ;select set video mode function
mov al, 13h                ;320x200 256 colors
int 10h                    ;set video mode.
                           ;Three registers pushed, FLAGS altered (by INT)
                           ;callback occurs, registers popped (by IRET)

Единственная разница в том, что int выталкивает FLAGS, CS и IP, а также очищает IF и TF. Программа возвращается в IRET (по адресу f000:1264), который отменяет все это.

«DB FE» по-прежнему отображается в DEBUG. Я думаю, что обратный вызов запускается только комбинацией 0xfe и 0x38. Сначала он пытается выполнить 0xfe, который в данном случае не является частью допустимого кода операции и ничего не делает (0xfe является частью кода операции inc, если за ним следуют допустимые байты), затем при обнаружении следующего 0x38 происходит обратный вызов.


person My life is a bug.    schedule 06.02.2018    source источник
comment
Вы можете убедиться, что таблица векторов прерываний содержит F000:1260 цель? Отслеживание вызовов int с помощью ПО-жучка, такого как debug.com, может иметь свои подводные камни. Также это чистый DOS на реальном HW или на какой-то виртуальной машине? Судя по скриншоту, это какая-то виртуальная машина или симулятор. Тогда код, который вы видите по этому адресу, может быть полностью поддельным, просто некоторая тень того, что симулятор действительно делает в фоновом режиме с вызовом int... Но пока ваше объяснение в вопросе звучит намного более разумно, чем эти идеи, я возможно, это слишком далеко, поэтому сначала проверьте IVT.   -  person Ped7g    schedule 07.02.2018
comment
Это ДОСБокс. То есть вы говорите, что выполнение int 1ch на самом деле не приводит к переходу в это место? Я добавил изображение записи IVT для int 1ch, местоположение 0000:0070.   -  person My life is a bug.    schedule 07.02.2018
comment
Итак, в конце концов, Dosbox является просто симулятором с упором на производительность и возможность запуска приложений, а не на полностью точное машинное моделирование, поэтому в некоторых местах он использует ярлыки с дополнительной внутренней реализацией вещей... Интересно, имеет смысл для меня сразу, но я никогда не думал об этом раньше и сам не сталкивался с такой проблемой.   -  person Ped7g    schedule 07.02.2018
comment
Нет, 0xfe не активирует его сам по себе. 0xfe также используется для кодирования INC r/m8.0xfe 0x38, хотя это недопустимая инструкция (она не также не кодирует допустимую инструкцию inc). Таким образом, эмулятор должен будет проверить как минимум следующий байт после 0xfe, чтобы определить, что делать.   -  person Michael Petch    schedule 07.02.2018


Ответы (1)


0xFE 0x38 не является определенным префиксом и/или инструкцией для реального процессора Intel x86. В DOSBox последовательность 0xFE 0x38 представляет собой специальную 4-байтовую инструкцию. Оставшиеся два байта составляют 16-битное значение, которое действует как индекс обратного вызова DOSBox. В этом случае индекс 0x0013.

Что это эффективно делает, так это вызывает сам DOSBox для выполнения запрошенной задачи. DOSBox выполнит любую необходимую обработку, установит регистры внутри эмулятора и затем вернется. Следующая инструкция — IRET (0xCF). Это завершит прерывание и продолжит обработку инструкций до вызова прерывания.

Я обнаружил это, глядя на код DOSBox. В частности, функция CALLBACK_SetupExtra:

case CB_IRET:
    if (use_cb) {
        phys_writeb(physAddress+0x00,(Bit8u)0xFE);  //GRP 4
        phys_writeb(physAddress+0x01,(Bit8u)0x38);  //Extra Callback instruction
        phys_writew(physAddress+0x02,(Bit16u)callback);     //The immediate word
        physAddress+=4;
    }
    phys_writeb(physAddress+0x00,(Bit8u)0xCF);      //An IRET Instruction

Этот код устанавливает обратные вызовы DOSBox, где после обратного вызова требуется IRET.

person Michael Petch    schedule 06.02.2018
comment
ну, технически FE это вариант inc [mem], второй 38 делает его неопределенным, в то время как, например, fe 05 11 00 ... кодирует inc byte [0x11]. Итак, FE является инструкцией INC на x86. - person Ped7g; 07.02.2018
comment
@ Ped7g Только fe /0 является inc на x86. fe /1 это dec r/m8, а остальные не определены. Вы не можете просто игнорировать расширенный код операции. - person fuz; 07.02.2018
comment
@fuz хорошо, это более точно ... в любом случае, после FE вы еще не можете сказать, недействителен ли код операции (какова была исходная формулировка ответа до того, как Майкл отредактировал его). В любом случае, это всего лишь незначительная деталь, ответ был достаточно хорош еще до редактирования. - person Ped7g; 07.02.2018