您的位置:首页 > 其它

DOS中使用扩展内存与XMS操作库设计

2008-12-27 23:54 288 查看
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使用实例执行结果:



本文到此结束!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: