DOS程序使用XMS


概述:
    作为常规内存的扩充,XMS(即扩充内存)的应用很广泛,它主要用于程序的数据存储空间,使用XMS时,需要在常规内存中开一个缓冲区,然后用移动内存块的方法进行数据交换。
    XMS 内存的存取是通过 XMS 驱动程序进行的,存取 XMS 前,必须先检测 XMS 驱动程序是否存在,然后获取驱动程序地址,通过远调用来使用它。检测 XMS 及获取驱动程序地址通过 INT 2FH 的 4300H 和 4310H 功能来进行的,一旦成功后,所有对 XMS 的操作都是先在 AH 内设置功能码,然后通过对驱动程序进行 CALL FAR 来完成。在调用时需要在内存中先定义一个 EMM 结构,里面包括移动的字节数,XMS内存的句柄等要用到的参数。

有关资料:

1.DOS 中断 2FH 的 4300H 及 4310H 功能

功能号 入口参数 出口参数
AX=4300H
XMS安装检测
  AL=80H 已安装XMS
AL<>80H XMS未安装
AX=4310H
取驱动程序地址
  ES:BX=驱动程序入口地址

2.远调用 XMS 驱动程序的功能表

功能号 入口参数 出口参数
AH=09H
分配XMS内存
DX=所需的KB AX=0001H 成功
则DX=XMS 内存句柄
AX=0000H 失败
AH=0AH
释放XMS内存
DX=XMS句柄 AX=0001H 成功
AX=0000H 失败
AH=0BH
移动XMS内存
DS:SI指向EMM结构 AX=0001H 成功
AX=0000H 失败

3.EMM 结构的格式

偏移量 大小 说明
00H Double word 要移动的字节数(必须是偶数)
04H Word 源句柄(0 表示常规内存)
06H Double word 源块中的偏移量
0AH Word 目的句柄(0 表示常规内存)
0CH Double word 目的块中的偏移量

汇编编程示例:

;定义 EMM 结构

EMM     DW    0,0         ;double word -- how many bytes to move
        DW    0           ;word -- source handle
        DW    0,0         ;double word -- source offset & segment
        DW    0           ;word -- target handle
        DW    0,0         ;double word -- target offset & segment
OFFXMS  DW    0           ;XMS驱动程序的入口地址
SEGXMS  DW    0

HANDLE_XMS    DW    0    ;申请到的XMS句柄


;以下程序检测及申请XMS内存

        mov    ax,4300h         ;检测有无XMS
        int    2fh
        cmp    al,80h
        jnz    no_xms

        mov    ax,4310h         ;保存XMS驱动程序地址
        int    2fh
        mov    offxms,bx
        mov    segxms,es

        mov    ah,9             ;分配XMS内存
        mov    dx,100           ;分配100KB
        call   dword ptr offxms
        or     ax,ax
        jz     no_more_xms      ;AX=0 则分配失败

        mov    xms_handle,dx

;以下程序将内存A000:0000处的64K字节移到XMS块中

        mov    emm,0
        mov    emm+2,1             ;10000H为64K
        mov    emm+4,0             ;source handle = 普通内存
        mov    emm+6,0             ;源地址A000:0000
        mov    emm+8,0a000h
        mov    bx,xms_handle
        mov    emm+0ah,bx          ;targat handle = XMS
        mov    emm+0ch,0           ;移动到XMS的起始地址
        mov    emm+0eh,0
        mov    si,offset emm
        mov    ah,0bh
        call   dword ptr offxms

;以下程序将XMS块中的64K字节移到内存A000:0000处

        mov    emm,0
        mov    emm+2,1             ;bytes = 10000H (64K)
        mov    bx,xms_handle
        mov    emm+4,bx            ;source handle
        mov    emm+6,0             ;source offset
        mov    emm+8,0
        mov    emm+0ah,0           ;target handle 0 for MEM
        mov    emm+0ch,0           ;target offset
        mov    emm+0eh,0a000h
        mov    si,offset emm
        mov    ah,0bh
        call   dword ptr offxms

;以下程序释放XMS内存

        mov    ah,0ah             ;free XMS memory
        mov    dx,cs:xms_handle
        call   dword ptr cs:offxms





(C) Copyright by LuoYunBin's Win32 ASM Page,http://asm.yeah.net