ITEEDU

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