如何使用C应用程序访问FreeDOS中的全部内存空间

时间:2019-05-10 20:13:29

标签: c memory dos

我有一个用C编写的嵌入式应用程序,可在486 / 386DX风格的处理器(http://www.dmp.com.tw/tech/vortex86dx)上的FreeDOS上运行。该计算机具有256MB的内存,但是我似乎无法访问大多数计算机。

我编写了一个简单的程序来研究(循环调用malloc()直到返回空指针),尽管每个malloc()请求的大小都会稍微影响结果,但始终限制在300kB左右。我的代码必须映射16位内存块,因为我的malloc()实现似乎只接受unsigned short参数。并不可怕,因为我只需要3MB左右,所以大约需要50个块(它是用于采集数据的循环缓冲区,因此这种环回方法并不那么麻烦)。由于我获得的内存远远超过16位(300k和64k),因此我知道这不完全是16位的问题。我猜想这与我在研究中了解到的640kB限制有关,但是我不知道这是编译器问题还是操作系统问题。

我正在使用Borland BC5编译器,并且尝试了对内存模型和编译器选项的各种调整,这些调整对结果的影响很小。我目前正在研究HIMEMX.EXE和JEMM386.EXE,但由于到目前为止我已经吠叫了很多错误的树,因此我认为值得提出一个问题。我也开始研究Linux,尽管这是一个重大的重大变化,因为代码是特定于DOS的,并且我对Linux的使用经验为零。

我希望只有一些设置或命令可以利用,而不必为我不熟悉的操作系统做一些巨大的移植。我的DOS安装当前仅包含将文件config.sys和sys.com复制到硬盘驱动器,因此,我没有访问上面的扩展内存可执行文件的经验。猜测只会使我陷入下一个难题,因此希望在这个古老部门工作过的人可以伸出援手,直到我有更多时间熟悉现代工具。

所以我应该更关注操作系统设置或编译器设置(或编译器本身)吗?

2 个答案:

答案 0 :(得分:2)

特别是对于malloc(),我记得Borland实现采用16位大小的参数。 Borland库的halloc()版本(以及相应的hfree()版本)具有“巨大”的内存模型,可以分配更大的块(大于64kb)。

JEMM386这是一个扩展的内存管理器,它将1Mb以上的内存分页到640K以上的“高内存”区域-该区域的大小仅为384Kb,并非全部可用于存储分页,这可能是您通过实验观察到的300Kb限制的原因。

要充分利用代码和数据的内存资源,必须使用DPMI(DOS保护模式接口)。 DPMI程序是真正的32位保护模式程序,具有访问DOS API的机制(这是Windows 3.x在Windows 95本身成为操作系统而不是基于DOS的图形环境之前工作的方式)。

DPMI程序在受保护而不是 real 模式下运行处理器。由于存在两种保护模式,因此这有点复杂。 16位80286保护模式(DPMI16)和32位80386保护模式(DPMI32)。就您而言,您只需要关注DPMI32。

对于Borland编译器,通过 DOS Power Pack 工具支持DPMI。但是Power Pack旨在与Borland C ++ 4.02和4.5x而非5.0一起使用。 This technical note,介绍了如何将Power Pack与BC ++ 5结合使用,但建议不要这样做。它指出它仅适用于命令行工具-不适用于IDE。就是说,这个other technical note然后说明了如何使其在IDE中工作,但是说明了BC ++ 5 RTL不起作用。总体而言,这听起来并不令人愉快。

但是,根本不需要考虑切换到Linux-您只需要使用支持DPMI32的工具链,并允许您在DOS环境中将代码构建为真正的32位代码。

合适的工具链可能包括:

除DJGPP以外,所有上述所有内容都需要第三方 DOS扩展器(DPMI主机),其中某些here列出。 DJGPP包括扩展器(如here所述),因此,如果不是最现代的话,它可能是最简单的选择(但Borland都不是)。请查阅工具链文档以确定您需要什么。使用第三方扩展程序的人的问题在于,尽管编译器可能继续可用,但扩展程序可能会消失(就像我认为的Digital Mars一样)。

答案 1 :(得分:1)

仅将旧的DOS设置为使用640 kiB的内存,而地址空间仅增加到1 MiB。

较新的技术包括"unreal mode"(我是第一次听说,但对我来说似乎很合逻辑)。

但是在DOS时代,您必须使用EMS和/或XMS。

这些是在可用内存窗口之外访问内存的技术。

EMS具有内存窗口,可以在其中映射额外内存的页面。

使用XMS,您有一个特殊的功能,该功能可以帮助您使用某个功能地址将数据复制到内存中。