前言

本文使用通俗易懂的表述,深入浅出地介绍DPMI和DOS Extender(以DOS/4GW为例)的理论和基本使用技术,旨在让对DPMI不太了解的程序员能了解DPMI在C语言中的实现方法。限于本人水平及资料匮乏,文中难免存在不当之处,望各位读者不吝赐教。

什么是DPMI和DOS Extender DPMI?

DPMI和DOS Extender DPMI是DOS保护模式接口(DOS Protected Mode Interface)的英文缩写,是在DOS平台下实现大内存编程的重要手段。

DPMI解决DOS使用大内存问题

众所周知,DOS默认支持管理的最大内存空间为640KB。

随着硬件科技的发展,在80年代末期、90年代初期,拥有超过640KB的内存的系统诞生了。

这就要求DOS能够使用和管理高于640KB部分的内存空间。

诞生DPMI

DPMI就是在这种背景下诞生的技术,它提出了Real Mode(实模式)和Protected Mode(保护模式)的概念。所谓Real Mode,就是DOS默认的工作模式,在这种模式下DOS最多只能管理640KB内存。

而Protected Mode是由DPMI平台提供的一种新模式,在这种模式下DOS可以管理16MB甚至更多的内存空间,这对于当时的计算机应用已经绰绰有余(事实上,超过16MB内存的计算机系统一直到1997年才得以普及)。

详细介绍DPMI

下面详细解释Protected Mode的实现方法。

首先需要指出,Protected Mode只是一个抽象概念,其具体实现依赖于DOS Extender(关于DOS Extender,还没有统一的中文翻译)。

DOS Extender是DPMI的具体应用,可以将它理解为一个程序。和Real Mode下的其它应用程序一样,它占用640KB中的一部分。

但是它可以让经过特殊设计的应用程序以它为平台运行。这样,这些应用程序就可以通过DOS Extender访问高于640KB的内存空间。 常见的DOS Extender包括DOS/16M、DOS/4G、DOS/4GW、DOS32A、Causeway等,它们都通过DPMI实现对大内存的管理。

Watcom C/C++和DOS/4GW Watcom C/C++

Open Watcom,前身是Watcom C/C++,现在一个免费开源的编译环境。

成立于1981年的WATCOM公司于1988年推出PC版的C语言编译器,或许是专心研究的缘故, Watcom C/C++是以在DOS下能够产生最佳化程序代码闻名于世的,许多写游戏和DOS Extender的厂商都指名要使用Watcom C/C++,因为不论是Borland C/C++还是Visual C/C++,它们产生的最佳化程序代码都比Watcom C/C++的最佳化程序代码差上一截。再加上当时最有名的DOS Extender厂商PharLap公司也是使用Watcom C/C++,因此Watcom C/C++在专业的C/C++程序员以及系统程序员心中是第一品牌的C/C++开发工具。

与当时DOS扩展器中的翘楚DOS/4GW联手,使员在DOS可以轻松地完成32位保护模式:32位的字长,4G的内存寻址能力,更全面的硬件访问。

这一切将Watcom C/C++打造成一把利器,当时很多商业游戏都使用它来编码,DOS时代的玩家可能还记得,许多游戏在运行之前都会先加载"DOS/4GW"这个扩展,然后才进入游戏本身,这就是Watcom + DOS/4GW的产物。

总之,Watcom C/C++在专业的C/C++员以及系统员 心中是第一名牌的开发工具。

不过到了上世纪90年代中叶四大编译器厂商大混战中(分别是Borland C/C++, Watcom C/C++, Visual C/C++, Symantec C/C++),Microsoft凭借自身又是操作系统厂商的优势对其它三家进行打压,比如说封装一套MFC,和Watcom及Symantec签订授权 条约后却只提供了一个低版本的MFC,自己的Visual C/C++捆绑的MFC使用高版本,这一来就势必造成不公,结果令Watcom及Symantec败北,Watcom也被Sybase收购。关于这段历 史,有兴趣的朋友可以去下载李维的《Borland 传奇》做更详细的了解。

到后来,Watcom C/C++作为一个开源自由项目出现在世人眼前,也就是我打算跟你介绍的Open Watcom(以下简称OW)。

现在的OW可以生成Win32、OS/2、Linux、DOS等平台下的执行,编译速度和后端优化效果依然是那么夺目。

它并没有强大的Integrated Development Environment(IDE,集成开发环境),但编译的目标程序的执行效率却比当时Borland和Microsoft的编译器编译的快很多。

因此,Watcom C/C++得到了许多程序员,尤其是游戏开发者的青睐。

在众多DOS Extender中,最出名的是由Rational Systems Inc.(现在更名为Tenberry Software)开发的DOS/16M、DOS/4G和DOS/4GW。

在许多老游戏的执行之初,我们都可以看到DOS/4GW的字样,这就说明这些游戏是通过DOS/4GW访问大内存的。

刚刚提到的三个DOS Extender虽然都是Rational Systems Inc.的产品,但还是有差别的。

DOS/16M是16位的Extender,它兼容许多16位编译器(比如Borland C 2.0);

DOS/4G和DOS/4GW都是32位的Extender,它只兼容32位的编译器。其中,DOS/4GW是DOS/4G为当时如日中天的Watcom C/C++制作的特别版,售价比较低,代价是最多只能管理16MB内存(不过在当时已经足够了)。Watcom C/C++与DOS/4GW的完美搭配 在众多实现DOS大内存程序设计的方法中,Watcom C/C++与DOS/4GW的搭配是最受欢迎的。

Watcom C/C++拥有无与伦比的程序执行效率;

而DOS/4GW不仅稳定,功能也十分强大(由于运行在保护模式下的程序往往在访问硬件时遇到困难,DOS/4GW比较好地解决了这个问题)。

Watcom C/C++如今已经成为了一款开源的免费软件,同时更名为Open Watcom C/C++,而DOS/4GW仍然是商业软件。

Open Watcom C/C++可以在其网站

http://www.openwatcom.org

下载

这个版本中包含了DOS/4GW。

在安装好Open Watcom C/C++后,要使用DOS/4GW编译和连接一个C/CPP文件,需要进行下面的步骤(以Open Watcom C/C++安装在 D:\OWATCOMC下为例):

在Open Watcom C/C++的安装目录下新建一个compile.bat文件,内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12


PATH D:\OWATCOMC\BINW


SET TEMP=D:\OWATCOMC\TEMP


SET INCLUDE=D:\OWATCOMC\H


SET WATCOM=D:\OWATCOMC\BINW\WCL386 /l=dos4g %1 DEL %1.obj

这个compile.bat文件调用WCL386,即Open Watcom C/C++的编译和连接器,来编译和连接你的程序。 如果要编译一个文件 d:\c\hello.c,则在DOS提示符下输入:D:\OWATCOMC\COMPILE d:\c\hello.c 这样就可以在 D:\OWATCOMC下生成 hello.exe

程序并不要做额外的更改,但你可以定义更多的大数组(但不是更大的数组),申请更大的内存空间(总和不超过16MB,如果使用DOS/4G就可以申请到总和多达64MB的内存空间)。