DOS中使用扩展内存与XMS操作库设计
作者:彭学周(Favory.Peng)
DOS系统常规内存指的是0-640K的内存区。在DOS下,一般的应用程序只能使用系统的常规内存,因而都要受到640KB内存的限制。而且由于DOS本身和config.sys文件中的安装的设备驱动程序和autoexec.bat文件中执行的内存驻留程序都要占用一些常规内存,所以应用程序能使用的常规内存是不到640K的。为了解决应用程序的内存需求问题最常用的方法就是使用扩展内存(XMS),扩展内存只能用在80286或更高档次的机器上,目前几乎所有使用DOS的机器上超过1M的内存都是扩展内存。扩展内存同样不能被DOS直接使用,DOS5.0以后提供了Himem.sys这个扩展内存管理程序,我们可以通过它来管理扩展内存。
加载方法:在config.sys文件中要加上一句话:DEVICE=C:/DOS/HIMEM.SYS,然后就能在程序中访问扩展内存了。利用mem.exe查看内存情况就可以看到你的物理内存1M以上的内存都被列为XMS扩展内存部分啦,我们就可以利用HIMEM.SYS提供的内存管理功能接口来使用XMS啦;
XMS的使用步骤如下:
1、加载驱动,在Config中加入DEVICE=C:/DOS/HIMEM.SYS;
2、获取驱动入口地址;
3、申请XMS内存获取句柄;
4、使用XMS内存(写入,读取);
5、根据句柄释放XMS内存;
XMS操作库:
DM&P DOS XMS Library 下载地址:http://www.dmp.com.tw/tech/dmp-lib/xms/
具体的C语言版本的XMS操作函数可以在网上直接搜索到,参考:http://www.blogjava.net/wudiasm/archive/2008/11/09/195680.html
本人用Pascal在TP7.0下面重新实现了这套函数库,希望对你有所帮助;
- {uxms.pas}
- {
- DOS XMS library is a DOS real mode and large memory model Pascal library.
- Because DOS is ran under real mode, programmer only can access RAM under 1MB.
- The memory user can use are 640 KB, Other 384 KB are reserved for ROM BIOS and other cards.
- XMS library provides DOS programmer a easy way to access RAM above 1 MB under DOS via XMS driver.
- For MS-DOS, add "DOS=HIGH" to you CONFIG.SYS will force MS-DOS to active XMS driver.
- ================================================================================
- 3F Medical Pascal XMS Library.
- Copyright (C) 2008 by Favory.Peng.
- This library is for 3F Medical product user only.
- }
- unit UXMS;
- interface
- uses DOS,CRT;
- type
- XMMS = record
- byte_count:LongInt; {bytes count}
- source_handle:word; {source handle}
- source_offset:Pointer;{source offset}
- dest_handle:word; {destination handle}
- dest_offset:Pointer; {destination offset}
- end;
- pXMMS = ^XMMS;
- pByte = ^Byte;
- pWord = ^Word;
- var
- XMS:Boolean;
- xms_func:LongInt;
- max_block,total_block:word;
- trans:XMMS;
- function XMS_Init:Boolean;
- function XMS_Allocate(len:word):word;
- function XMS_Free(handle:word):Boolean;
- function XMS_GetVer:word;
- function XMS_GetFree:Boolean;
- function XMS_Lock(handle:word):Boolean;
- function XMS_ULock(handle:word):Boolean;
- function XMS_Copy(PT:pXMMS):Boolean;
- function XMS_CopyToXMS(DstHandle:word;lDstOffset:Pointer;pSrc:Pointer;lLen:LongInt):Boolean;
- function XMS_CopyFromXMS(pDst:Pointer;SrcHandle:word;lSrcOffset:Pointer;lLen:LongInt):Boolean;
- implementation
- {Initialize XMS driver and get control function address}
- function XMS_Init:Boolean;
- var
- is_exist:byte;
- seg1,off1:word;
- ptr_xms_func:^word;
- begin
- asm
- mov ax,4300h
- int 2fh
- mov is_exist,al
- end;
- if is_exist<>$80 then
- begin
- XMS_Init:=False;
- end else
- begin
- asm
- mov ax,4310h
- Int 2fh
- mov seg1,ES
- mov off1,BX
- end;
- ptr_xms_func:=@xms_func;
- ptr_xms_func^:=off1;
- inc(ptr_xms_func);
- ptr_xms_func^:=seg1;
- XMS_Init:=True;
- end;
- end;
- {Allocate XMS memory}
- function XMS_Allocate(len:word):word;
- var
- result,handle:word;
- begin
- asm
- mov dx,len
- mov ah,9
- call xms_func
- mov result,ax
- mov handle,dx
- end;
- if result=0 then
- XMS_Allocate:=0
- else
- XMS_Allocate:=handle;
- end;
- {Free allocated XMS memory}
- function XMS_Free(handle:word):Boolean;
- var
- result:word;
- begin
- asm
- mov dx,handle
- mov ah,10
- call xms_func
- mov result,ax
- end;
- if result=0 then
- XMS_Free:=False
- else
- XMS_Free:=True;
- end;
- {Get XMS driver version}
- function XMS_GetVer:word;
- var
- version:word;
- begin
- asm
- mov ah,0
- call xms_func
- mov version,ax
- end;
- XMS_GetVer:=version;
- end;
- {Query free memory and maximum available space}
- function XMS_GetFree:Boolean;
- var
- error_code:byte;
- begin
- error_code:=$ff;
- if XMS then
- begin
- asm
- mov ah,8
- call xms_func
- mov max_block,ax
- mov total_block,dx
- mov error_code,bl
- end;
- end;
- if error_code=$ff then
- XMS_GetFree:=False
- else
- XMS_GetFree:=True;
- end;
- {Lock Block}
- function XMS_Lock(handle:word):Boolean;
- var
- result:word;
- begin
- if XMS then
- begin
- asm
- mov ah,0ch
- mov dx,handle
- call xms_func
- mov result,ax
- end;
- end;
- if result=0 then
- XMS_Lock:=false
- else
- XMS_Lock:=True;
- end;
- {UNLock Block}
- function XMS_ULock(handle:word):Boolean;
- var
- result:word;
- begin
- if XMS then
- begin
- asm
- mov ah,0dh
- mov dx,handle
- call xms_func
- mov result,ax
- end;
- end;
- if result=0 then
- XMS_ULock:=False
- else
- XMS_ULock:=True;
- end;
- {Copy XMS memory}
- function XMS_Copy(PT:pXMMS):Boolean;
- var
- xoff,result:word;
- begin
- result:=$ff;
- if XMS then
- begin
- xoff:=Ofs(PT^);
- asm
- mov ah,0bh
- mov si,xoff
- call xms_func
- mov result,ax
- end;
- end;
- if result=0 then
- begin
- XMS_Copy:=False;
- end else
- begin
- XMS_Copy:=True;
- end;
- end;
- {Copy memory buffer to XMS}
- function XMS_CopyToXMS(DstHandle:word;lDstOffset:Pointer;pSrc:Pointer;lLen:LongInt):Boolean;
- begin
- trans.byte_count:=llen;
- trans.source_handle:=0;
- trans.source_offset:=pByte(pSrc);
- trans.dest_handle:=DstHandle;
- trans.dest_offset:=lDstOffset;
- XMS_CopyToXMS:=XMS_Copy(@trans);
- end;
- {Copy XMS to memory buffer}
- function XMS_CopyFromXMS(pDst:Pointer;SrcHandle:word;lSrcOffset:Pointer;lLen:LongInt):Boolean;
- begin
- trans.byte_count:=llen;
- trans.source_handle:=SrcHandle;
- trans.source_offset:=lSrcOffset;
- trans.dest_handle:=0;
- trans.dest_offset:=pByte(pDst);
- XMS_CopyFromXMS:=XMS_Copy(@trans);
- end;
- {init_unit}
- begin
- XMS:=XMS_Init;
- XMS_GetFree;
- end.
测试实例:100bytes数据拷贝到XMS中,程序赋值,从XMS恢复100Bytes的值。
- {UXMSTEST.pas}
- {
- XMS example for XMS library, copyright (C) 2008 by Favory.Peng,
- This example will show you how to XMS library.
- }
- program uxmstest;
- uses dos,crt,uxms;
- var
- szStr:array[0..99] of Byte;
- i,xms_handle:word;
- nStrLen:LongInt;
- {main}
- begin
- clrscr;
- for i:=0 to 99 do
- begin
- szStr[i]:=i;
- end;
- nStrLen:=100;
- if XMS_GetFree then writeln('Free memory: Max=',max_block,' KB, total=',total_block,' KB.');
- xms_handle:=XMS_Allocate(1);
- if xms_handle=0 then
- writeln('Allocate failed!')
- else begin
- writeln('Allocate 1KB memory: Handle=',xms_handle);
- end;
- if XMS_GetFree then writeln('Free memory: Max=',max_block,' KB, total=',total_block,' KB.');
- if XMS then writeln('XMS Version: ',XMS_GetVer);
- writeln('--------------------------------------------------------------------------');
- for i:=0 to 99 do
- begin
- write(szStr[i],',');
- end;
- writeln;
- writeln('1. Copy buffer to XMS..... buffer size=',nStrLen);
- XMS_CopyToXMS(xms_handle,Pointer(0),@szStr,nStrLen);
- writeln('2. Reset buffer....');
- for i:=0 to 99 do
- begin
- szStr[i]:=0;
- write(szStr[i],',');
- end;
- writeln;
- XMS_CopyFromXMS(@szStr,xms_handle,Pointer(0),nStrLen);
- writeln('3. Restore buffer....');
- for i:=0 to 99 do
- begin
- write(szStr[i],',');
- end;
- writeln;
- writeln('--------------------------------------------------------------------------');
- XMS_Free(xms_handle);
- if XMS_GetFree then writeln('Free memory: Max=',max_block,' KB, total=',total_block,' KB.');
- readkey;
- end.
XMS操作单元UXMS.PAS:
UXMS使用实例执行结果:
本文到此结束!
本文介绍了如何在DOS下通过Pascal语言实现XMS库,以访问1MB以上的RAM。XMS库允许程序员在DOS真实模式下方便地使用扩展内存。文章提供了详细的库函数实现,并通过一个示例程序演示了内存分配、复制和释放等功能。

3927

被折叠的 条评论
为什么被折叠?



