Я много экспериментировал с программированием на ассемблере в MS-DOS. Я читал, что Windows 3.1 действует как хост DPMI для программ DOS и что DPMI использует прерывание 31h для вызовов функций.
Итак, давайте попробуем. Я открываю приглашение DOS в Windows 3.1...
C:\WINDOWS>debug
-a100
23A4:0100 mov ax,0400
23A4:0103 int 31
23A4:0105
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=23A4 ES=23A4 SS=23A4 CS=23A4 IP=0100 NV UP EI PL NZ NA PO NC
23A4:0100 B80004 MOV AX,0400
-p
AX=0400 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=23A4 ES=23A4 SS=23A4 CS=23A4 IP=0103 NV UP EI PL NZ NA PO NC
23A4:0103 CD31 INT 31
-p
Значит что-то явно не работает.
Я пытаюсь снова, используя команду T
race вместо P
roceed. Таким образом, он фактически войдет внутрь обработчика прерывания, а не пропустит его.
AX=0400 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=23A4 ES=23A4 SS=23A4 CS=23A4 IP=0103 NV UP EI PL NZ NA PO NC
23A4:0103 CD31 INT 31
-t
AX=0400 BX=0000 CX=0000 DX=0000 SP=FFE8 BP=0000 SI=0000 DI=0000
DS=23A4 ES=23A4 SS=23A4 CS=F000 IP=FF01 NV UP DI PL NZ NA PO NC
F000:FF01 7261 JB FF64
-
Посмотрим, что будет выполнено...
-u
F000:FF01 7261 JB FF64
F000:FF03 63 DB 63
F000:FF04 6C DB 6C
F000:FF05 65 DB 65
F000:FF06 20564D AND [BP+4D],DL
F000:FF09 205669 AND [BP+69],DL
⋮
F000:FF18 53 PUSH BX
F000:FF19 0000 ADD [BX+SI],AL
F000:FF1B 0000 ADD [BX+SI],AL
F000:FF1D 0000 ADD [BX+SI],AL
F000:FF1F 0000 ADD [BX+SI],AL
-
...Да, это не похоже на то, что должно быть выполнено. На самом деле байт-код подозрительно похож на текст ASCII. Конечно же...
-df000:ff01
F000:FF00 72 61 63 6C 65 20 56-4D 20 56 69 72 74 75 61 racle VM Virtua
F000:FF10 6C 42 6F 78 20 42 49 4F-53 00 00 00 00 00 00 00 lBox BIOS.......
F000:FF20 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
F000:FF30 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
F000:FF40 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
F000:FF50 00 58 4D CF CF 89 C0 89-C0 89 C0 89 C0 89 C0 FC .XM.............
F000:FF60 5F 53 4D 5F 7D 1F 02 05-FF 00 00 00 00 00 00 00 _SM_}...........
F000:FF70 5F 44 4D 49 5F 58 C2 01-00 10 0E 00 0A 00 25 00 _DMI_X........%.
F000:FF80 00 .
-
Это явно не обработчик DPMI. В любом случае, если я пройду мимо JB FF64
, он перейдет к DB 63
("c" в Oracle), и это приведет к ошибке недопустимой инструкции. В качестве альтернативы, если флаг переноса установлен, он совершит переход и встретит то, что интерпретируется как инструкция JGE FF85
. Если флаги таковы, что он не выполняет переход, он в конечном итоге достигнет другой недопустимой инструкции. В противном случае он увеличит байт в [BX+SI]
на значение в AL
105 раз, увеличит байт 77 байт после этого на значение в BL
один раз и, наконец, перезагрузит виртуальную машину, потому что следующая инструкция — это сброс в реальном режиме. вектор. (В режиме v86, но, думаю, Windows 3.1 это позволяет.)
Короче говоря, ясно, что в INT 31H не установлен обработчик DPMI, как, по-видимому, должно быть. Несколько дополнительных битов информации:
Вы могли заметить, что я набрал только
int 31
, а неint 31h
. Это не ошибка;debug
везде использует и ожидает шестнадцатеричный код. И, как вы видели, он не пытался выполнить растровый шрифт графического режима как код. :ПЯ попробовал это с Qualitas MAX вместо Windows 3.1, а также вообще без хоста DPMI, и в обоих случаях получил одинаковый результат. (Конечно, кроме диалогового окна ошибки Windows 3.1.)
Имея это в виду, может ли кто-нибудь сказать мне, что я делаю неправильно?