You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

32位DOS汇编程序内存分配及DPMI调用实现咨询

32位DOS DPMI程序内存分配方案

一、用户现有代码与编译步骤

汇编程序代码

; hellod.asm
.386
.model flat
.code
_start:
mov ax, 901h  ; Enable virtual interrupts.
int 31h
mov ah, 9
mov edx, offset message
int 21h
mov ax, 4c00h  ; exit(EXIT_SUCCESS).
int 21h
.const
message db 'Hello, World!', 13, 10, '$'
.stack
db 100h dup (?)
end _start

编译命令

wasm -q -fo=hellod.obj hellod.asm
wlink format os2 lx op align=16 op internalrelocs op stub=dos32a.exe op quiet op noext n hellod.exe f hellod.obj 

二、内存分配解决方案(基于DPMI调用)

要在平展内存模型下实现无libc的动态内存分配,直接使用DPMI中断0x31的内存管理子功能即可,分配的是线性地址,无需修改段寄存器。

核心DPMI调用说明

1. 分配内存块(子功能0x0001)

  • 功能:分配指定大小的线性内存块,返回块的基地址
  • 寄存器参数:
    • AX = 0x0001
    • EBX = 要分配的字节数(必须对齐到4KB,即0x1000的倍数)
  • 返回值:
    • 成功:CF=0,EAX=分配的线性基地址
    • 失败:CF=1,AX=错误码

2. 释放内存块(子功能0x0002)

  • 功能:释放已分配的内存块
  • 寄存器参数:
    • AX = 0x0002
    • EAX = 要释放的内存块基地址
  • 返回值:
    • 成功:CF=0
    • 失败:CF=1,AX=错误码

3. 调整内存块大小(子功能0x0003)

  • 功能:对已分配的内存块进行扩容/缩容,适合增量分配场景
  • 寄存器参数:
    • AX = 0x0003
    • EAX = 原内存块基地址
    • EBX = 新的内存块字节数(需对齐到4KB)
  • 返回值:
    • 成功:CF=0,EAX=新的内存块基地址(可能与原地址相同)
    • 失败:CF=1,AX=错误码

集成内存操作的示例代码

; hellod_mem.asm
.386
.model flat
.code
_start:
    mov ax, 901h  ; Enable virtual interrupts.
    int 31h

    ; ---------- 分配4KB内存块(可根据用户输入调整EBX值) ----------
    mov ax, 0001h
    mov ebx, 1000h ; 4KB = 0x1000字节
    int 31h
    jc alloc_error ; CF=1则分配失败

    mov [mem_ptr], eax ; 保存分配的线性地址

    ; ---------- 写入测试数据到分配的内存 ----------
    mov ecx, 1000h/4 ; 循环次数:4KB / 4字节(每个DWORD)
    mov edi, [mem_ptr]
    mov eax, 0xdeadbeef
    rep stosd ; 填充内存

    ; ---------- 读取验证内存数据(可选) ----------
    mov ecx, 1000h/4
    mov esi, [mem_ptr]
verify_loop:
    lodsd
    cmp eax, 0xdeadbeef
    jne verify_error
    loop verify_loop

    ; ---------- 释放内存块 ----------
    mov ax, 0002h
    mov eax, [mem_ptr]
    int 31h
    jc free_error

    ; 打印成功信息
    mov ah, 9
    mov edx, offset success_msg
    int 21h
    jmp exit_program

alloc_error:
    mov edx, offset alloc_err_msg
    jmp print_error

verify_error:
    mov edx, offset verify_err_msg
    jmp print_error

free_error:
    mov edx, offset free_err_msg

print_error:
    mov ah, 9
    int 21h

exit_program:
    mov ax, 4c00h  ; exit(EXIT_SUCCESS).
    int 21h

.const
success_msg db 'Memory allocated, written, verified and freed successfully!', 13, 10, '$'
alloc_err_msg db 'Failed to allocate memory!', 13, 10, '$'
verify_err_msg db 'Memory verification failed!', 13, 10, '$'
free_err_msg db 'Failed to free memory!', 13, 10, '$'
message db 'Hello, World!', 13, 10, '$'

.data?
mem_ptr dd ? ; 保存分配的内存地址

.stack
db 100h dup (?)
end _start

三、DPMI相关优质文档推荐

  • DPMI Specification Version 1.0:官方权威标准文档,涵盖所有DPMI中断调用的参数、返回值与行为细节
  • DOS Protected Mode Interface (DPMI) Programmer's Reference:第三方整理的实用指南,包含常见场景的代码示例与注意事项
  • OpenWatcom Assembler Documentation:针对你使用的工具,提供平展模型下DPMI编程的具体实现细节

四、注意事项

  • 内存分配大小必须对齐到4KB(0x1000字节),若用户输入不是4KB倍数,需向上取整
  • 分配的内存默认具备读、写、执行权限,符合你的需求,无需额外权限设置
  • 程序退出前务必释放所有已分配的内存,避免DOS环境下的内存泄漏

内容的提问来源于stack exchange,提问作者pts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 09:46:32