问题描述
我一直在尝试在 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
所以有些东西显然不起作用。
我再试一次,使用 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
(“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 (将#修改为@)