为什么即使 DPMI 主机处于活动状态,INT 31H 也没有正确设置?

问题描述

我一直在尝试在 MS-DOS 中进行汇编编程。我读过 Windows 3.1 充当 DOS 程序的 DPMI 主机,并且 DPMI 使用中断 31h 进行函数调用。

所以让我们试一试。我在 Windows 3.1 中打开 DOS 提示符...

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

And suddenly I'm back in Windows with an error box: This application has violated system integrity due to execution of an invalid instruction and will be terminated. Quit all applications,quit Windows,and then restart your computer.

所以有些东西显然不起作用。

我再试一次,使用 Trace 命令而不是 Proceed。这样它实际上会进入中断处理程序,而不是跳过它。

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(“Oracle”中的“c”),这就是导致无效指令错误的原因。或者,如果设置了进位标志,它将进行跳转并遇到它解释为 JGE FF85 指令的内容。如果标志是这样的,它不进行跳转,它最终会到达另一个无效指令。否则,它会将 [BX+SI] 处的字节增加 AL 中的值 105 次,之后将 BL 中的值增加一次 77 字节,最后重新启动VM,因为下一条指令是实模式复位向量。 (在 v86 模式下,但我猜 Windows 3.1 允许这样做。)

长话短说,很明显在 INT 31H 没有安装 DPMI 处理程序,就像显然应该有的那样。一些额外的信息:

  • 您可能已经注意到我只输入了 int 31,而不是 int 31h。这不是错误; debug 在任何地方都使用并期望十六进制。正如您所见,它并没有尝试将图形模式位图字体作为代码执行。 :P

  • 我尝试使用 Qualitas MAX 而不是 Windows 3.1,并且根本没有 DPMI 主机,并且在两种情况下都得到了相同的结果。 (当然,减去 Windows 3.1 错误对话框。)

考虑到这一点,谁能告诉我我做错了什么?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)