如何为 DOS 创建小型 32 位 (i386) 可执行文件?

pts*_*pts 5 x86 assembly dos protected-mode

我想为 DOS 创建小型 32 位 (i386) 可执行文件。

作为参考,下面是我的小型 16 位 (8086) DOS 可执行文件的 NASM 汇编源代码:

; $ nasm -o hi16.com hi16.nasm  # 26 bytes.
bits 16
org 0x100
mov dx, msg  ; 16-bit pointer to string.
mov ah, 9  ; Print message.
int 0x21
ret  ; exit(0).
msg: db 'Hello, World!', 13, 10, '$'
Run Code Online (Sandbox Code Playgroud)

由于我想在 32 位 DOS 可执行文件中使用超过 1 MiB 的内存,因此我很可能需要一个DOS 扩展器。在查看了多个 DOS 扩展程序之后,我决定尝试WDOSX,它似乎具有最小的存根(用于设置保护模式的 .exe 前缀): WDOSX.DX (请参阅此处如何获取它)只有 9720 字节。我的(想要的)小型 32 位 DOS 可执行文件的源代码是:

; $ nasm -o hi32.exe hi32.nasm  # 37+9720 bytes.
bits 32
wdosx_dx_start:
incbin "WDOSX.DX"  ; ~9720 bytes.   
org wdosx_dx_start-$
mov ax, 0x901
int 0x31  ; Enable virtual interrupts.
mov edx, msg  ; 32-bit pointer to string.
mov ah, 9  ; Print message.
int 0x21
mov ax, 0x4c00  ; exit(0).
int 0x21
msg: db 'Hello, World!', 13, 10, '$'
Run Code Online (Sandbox Code Playgroud)

这两个可执行文件(hi16.com 和 hi32.exe)都可以在 DOSBox 中开箱即用。通过使用DPMI 函数 0x0501,我的 32 位 DOS 程序将能够分配大于 1 MiB 的内存块,从而实现我的目标。

我的问题:是否有一个比 WDOSX.DX(9720 字节)更小的存根我可以使用?WDOSX 提供了 DPMI 0.9 主机的许多功能,而我不需要其中的大部分功能,例如我不需要支持许多二进制格式(例如 LE、PE)、VCPI、INT15、32 位 DOS API(所有功能) )、鼠标API,大部分是DPMI API。

我需要的功能:

  • 如果有 DPMI 主机(例如 Windows 中的 DOS 窗口或正在运行的 HDPMI32.EXE),它必须工作;如果 XMS 可用(但没有 v8086),它必须工作。我不关心其他环境,例如EMM386、VCPI、INT15。
  • 分配几 MiB 内存。
  • 程序退出时,释放分配的内存。
  • 按名称打开 DOS 文件、读取它、写入它、关闭它。如果我必须在低内存地址(<1 MiB,由 DOS 使用)和我分配的大缓冲区之间手动复制数据,那也没关系。

我正在寻找代码示例的链接或使用 XMS(虚幻模式?)并使用 DPMI API 完成这些功能的实现。

pts*_*pts 2

TL;DR编写 32 位 DOS 程序可实现的最小开销是 5800 .. 9800 字节。

我四处寻找 DOS 扩展程序,以下是我发现的:

  • 可以基于 PMODE 3.07 源代码构建解决方案,在程序中提供 <7500 字节的 DOS 扩展器开销(如果压缩则为 5800 字节),但由于手动设置和重定位,它需要大量工作。TASM 源代码可用。
  • D3X dx3lite.exe 可以开箱即用地压缩 8200 字节。TASM 源代码可用。目前只有针对Adam + 重定位二进制格式专门修改的 FASM 汇编器可用于开发,但应该可以使用 NASM 生成目标文件(ELF、OMF 或 COFF)并手动转换。
  • 压缩了 9720 字节的 WDOSX 0.97 是一个方便的选择,因为它不需要任何标头,并且无需重定位即可工作。
  • 其他的则不完整或增加至少 10000 字节的开销。

有关我考虑过的每个 DOS 扩展器以及它们增加的开销的更多详细信息:

  • Xi 开发系统 1997-08-15:4303 字节;不支持 VCPI、不进行重定位、没有文件 I/O
  • SYSTEM 64 v1.210:6392字节,实际程序由于NUL块而长了16408字节;大多数 DOS 文件 I/O 功能丢失
  • PMODE 3.07:7048字节,由于DOS .exe头中的NUL块,实际程序长了424字节
  • RAW32 r3:7270字节,实际程序由于NUL块而长了4186字节,实际程序使DOSBox崩溃
  • PMODE 2.05:7937字节,由于NUL块,实际程序长了5867字节
  • D3X d3xlite.exe 2022-06-13 作者:CandyMan:压缩 8200 字节
  • WDOSX 0.97:压缩 9720 字节
  • PMODE/W 1.22:10286 字节
  • EOS 3.0.5 eoslite.obj:使用 WWPACK 压缩时为 10800 字节,默认未压缩
  • D3XX d3x.exe 2022-08-01:10908 字节
  • Pro32版本17以及与Pass32 2.5汇编器一起分发的版本:11273字节,创建的.exe程序使DOSBox崩溃
  • D3X 0.90 2004-10-09: 11880,由于NUL块,实际程序长了4800字节
  • PMODE/W 1.33:11783 字节
  • ZRDX:12400字节
  • EOS 3.0.5 weoslite.exe:使用 WWPACK 压缩时为 13078 字节,默认压缩
  • DOS/4GW、DOS/32A、PMODE/W、PMODE/DJ 等甚至添加了超过 14000 字节。
  • DOSX 附带 Symantec C++ 6.1 21549 字节