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