[ Last edited by pkuwc on 2010-3-1 at 11:15 ]
Gemini 解答
结论:支持 DPMI 1.0 且包含 TSR 功能的开发包存在,需区分「运行时依赖」与「开发工具支持」,当年常见选择为 Watcom C/C++ 10.0+ 或 DJGPP(GCC for DOS),但需注意其运行时组件的兼容性约束。
技术解释与背景补充
DPMI 1.0 的核心差异
DPMI 0.9 仅支持 16 位客户端与 16 位主机(如早期 Windows 3.x、DOS4GW 等),而 DPMI 1.0 新增了 32 位客户端 支持(通过 DPMI 0x0300 功能调用进入 32 位保护模式),同时扩展了内存管理(如物理内存映射)、中断重定向等功能。TSR(内存驻留程序)在 DPMI 1.0 中需处理「保护模式下的中断钩子」与「客户端/主机的权限隔离」,这是当年开发包的主要实现难点。当年常见开发包的支持情况
- Borland 系列(Turbo C++ 3.0、Borland C++ 3.1):其自带的 DPMI 开发包(如
DPMI16BI.OVL、RTM.EXE)基于 DPMI 0.9 设计,仅支持 16 位保护模式 TSR,无法直接使用 DPMI 1.0 的 32 位特性,这是原帖提到「只能支持到 0.9」的原因。- Watcom C/C++ 10.0+:Watcom 的 DPMI 运行时(
DPMISTUB.EXE或内置 stub)原生支持 DPMI 1.0,且提供了_dos_keep等扩展函数用于 32 位保护模式 TSR 的内存驻留。其 TSR 实现通过「注册 DPMI 中断回调」(而非直接修改实模式中断向量)来兼容保护模式环境,可稳定使用 DPMI 1.0 的 TSR 功能。- DJGPP(GCC for DOS):基于 GNU 工具链的 DOS 移植版,使用
CWSDPMI(DPMI 1.0 主机)作为运行时,支持 32 位保护模式 TSR。通过_go32_dpmi_chain_protected_mode_interrupt_vector等函数可实现保护模式下的中断钩子,且CWSDPMI可向下兼容 DPMI 0.9 程序。- DPMIONE:原帖提到的 DPMIONE 是早期第三方 DPMI 1.0 实现,但专注于「32 位应用程序运行」而非「TSR 开发支持」,因此缺少驻留相关的库函数,这是其无法满足需求的原因。
兼容性问题的说明
原帖希望「DPMI16BI.OVL 和 RTM.EXE 向下兼容」,但 Watcom/DJGPP 的运行时组件(如DPMISTUB.EXE、CWSDPMI.EXE)本身就是独立的 DPMI 主机或 stub,无需依赖 Borland 的DPMI16BI.OVL。若需兼容旧程序,可通过「实模式 → DPMI 0.9 → DPMI 1.0」的嵌套模式运行,但 TSR 需额外处理模式切换时的内存布局问题。当年误解的成因
Borland 系列编译器在 DOS 时代的普及度极高,其自带的 DPMI 开发包是多数用户的「默认选择」,导致很多人误以为「所有开发包都只支持 DPMI 0.9」。而 Watcom/DJGPP 等支持 DPMI 1.0 的工具链因学习曲线较陡(如 Watcom 的内存模型、DJGPP 的 Unix-like 语法),在当年的中文社区中普及度较低,相关资料也较少。
补充建议(基于当年技术背景)
若需开发 DPMI 1.0 TSR,优先选择 Watcom C/C++ 10.0+:其文档(如《Watcom C/C++ Programmer's Guide》)明确说明了保护模式 TSR 的实现步骤,且运行时兼容性较好。若坚持使用 Borland 工具链,需自行扩展
DPMI16BI.OVL的功能(如手动调用 DPMI 1.0 的中断注册函数),但这涉及底层汇编修改,稳定性难以保证。
