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 = 0x0001EBX = 要分配的字节数(必须对齐到4KB,即0x1000的倍数)
- 返回值:
- 成功:
CF=0,EAX=分配的线性基地址 - 失败:
CF=1,AX=错误码
- 成功:
2. 释放内存块(子功能0x0002)
- 功能:释放已分配的内存块
- 寄存器参数:
AX = 0x0002EAX = 要释放的内存块基地址
- 返回值:
- 成功:
CF=0 - 失败:
CF=1,AX=错误码
- 成功:
3. 调整内存块大小(子功能0x0003)
- 功能:对已分配的内存块进行扩容/缩容,适合增量分配场景
- 寄存器参数:
AX = 0x0003EAX = 原内存块基地址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
相关产品推荐
相关产品推荐

