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

本文介绍了如何在DOS下通过Pascal语言实现XMS库,以访问1MB以上的RAM。XMS库允许程序员在DOS真实模式下方便地使用扩展内存。文章提供了详细的库函数实现,并通过一个示例程序演示了内存分配、复制和释放等功能。
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下面重新实现了这套函数库,希望对你有所帮助;
  1. {uxms.pas}
  2. {
  3. DOS XMS library is a DOS real mode and large memory model Pascal library.
  4. Because DOS is ran under real mode, programmer only can access RAM under 1MB.
  5. The memory user can use are 640 KB, Other 384 KB are reserved for ROM BIOS and other cards.
  6. XMS library provides DOS programmer a easy way to access RAM above 1 MB under DOS via XMS driver.
  7. For MS-DOS, add "DOS=HIGH" to you CONFIG.SYS will force MS-DOS to active XMS driver.
  8. ================================================================================
  9. 3F Medical Pascal XMS Library.
  10. Copyright (C) 2008 by Favory.Peng.
  11. This library is for 3F Medical product user only.
  12. }
  13. unit UXMS;
  14. interface
  15. uses DOS,CRT;
  16. type
  17.   XMMS = record
  18.     byte_count:LongInt;   {bytes count}
  19.     source_handle:word;   {source handle}
  20.     source_offset:Pointer;{source offset}
  21.     dest_handle:word;     {destination handle}
  22.     dest_offset:Pointer;  {destination offset}
  23.   end;
  24.   pXMMS = ^XMMS;
  25.   pByte = ^Byte;
  26.   pWord = ^Word;
  27. var
  28.   XMS:Boolean;
  29.   xms_func:LongInt;
  30.   max_block,total_block:word;
  31.   trans:XMMS;
  32.   function XMS_Init:Boolean;
  33.   function XMS_Allocate(len:word):word;
  34.   function XMS_Free(handle:word):Boolean;
  35.   function XMS_GetVer:word;
  36.   function XMS_GetFree:Boolean;
  37.   function XMS_Lock(handle:word):Boolean;
  38.   function XMS_ULock(handle:word):Boolean;
  39.   function XMS_Copy(PT:pXMMS):Boolean;
  40.   function XMS_CopyToXMS(DstHandle:word;lDstOffset:Pointer;pSrc:Pointer;lLen:LongInt):Boolean;
  41.   function XMS_CopyFromXMS(pDst:Pointer;SrcHandle:word;lSrcOffset:Pointer;lLen:LongInt):Boolean;
  42. implementation
  43. {Initialize XMS driver and get control function address}
  44. function XMS_Init:Boolean;
  45. var
  46.   is_exist:byte;
  47.   seg1,off1:word;
  48.   ptr_xms_func:^word;
  49. begin
  50.   asm
  51.     mov ax,4300h
  52.     int 2fh
  53.     mov is_exist,al
  54.   end;
  55.   if is_exist<>$80 then
  56.   begin
  57.     XMS_Init:=False;
  58.   end else
  59.   begin
  60.     asm
  61.       mov ax,4310h
  62.       Int 2fh
  63.       mov seg1,ES
  64.       mov off1,BX
  65.     end;
  66.     ptr_xms_func:=@xms_func;
  67.     ptr_xms_func^:=off1;
  68.     inc(ptr_xms_func);
  69.     ptr_xms_func^:=seg1;
  70.     XMS_Init:=True;
  71.   end;
  72. end;
  73. {Allocate XMS memory}
  74. function XMS_Allocate(len:word):word;
  75. var
  76.   result,handle:word;
  77. begin
  78.   asm
  79.     mov dx,len
  80.     mov ah,9
  81.     call xms_func
  82.     mov result,ax
  83.     mov handle,dx
  84.   end;
  85.   if result=0 then
  86.     XMS_Allocate:=0
  87.   else
  88.     XMS_Allocate:=handle;
  89. end;
  90. {Free allocated XMS memory}
  91. function XMS_Free(handle:word):Boolean;
  92. var
  93.   result:word;
  94. begin
  95.   asm
  96.     mov dx,handle
  97.     mov ah,10
  98.     call xms_func
  99.     mov result,ax
  100.   end;
  101.   if result=0 then
  102.     XMS_Free:=False
  103.   else
  104.     XMS_Free:=True;
  105. end;
  106. {Get XMS driver version}
  107. function XMS_GetVer:word;
  108. var
  109.   version:word;
  110. begin
  111.   asm
  112.     mov ah,0
  113.     call xms_func
  114.     mov version,ax
  115.   end;
  116.   XMS_GetVer:=version;
  117. end;  
  118. {Query free memory and maximum available space}
  119. function XMS_GetFree:Boolean;
  120. var
  121.   error_code:byte;
  122. begin
  123.   error_code:=$ff;
  124.   if XMS then
  125.   begin
  126.     asm
  127.       mov ah,8
  128.       call xms_func
  129.       mov max_block,ax
  130.       mov total_block,dx
  131.       mov error_code,bl
  132.     end;
  133.   end;
  134.   if error_code=$ff then
  135.     XMS_GetFree:=False
  136.   else
  137.     XMS_GetFree:=True;
  138. end;
  139. {Lock Block}
  140. function XMS_Lock(handle:word):Boolean;
  141. var
  142.   result:word;
  143. begin
  144.   if XMS then
  145.   begin
  146.      asm
  147.        mov ah,0ch
  148.        mov dx,handle
  149.        call xms_func
  150.        mov result,ax
  151.      end;
  152.   end;
  153.   if result=0 then
  154.      XMS_Lock:=false
  155.   else
  156.      XMS_Lock:=True;
  157. end;
  158. {UNLock Block}
  159. function XMS_ULock(handle:word):Boolean;
  160. var
  161.   result:word;
  162. begin
  163.   if XMS then
  164.   begin
  165.      asm
  166.        mov ah,0dh
  167.        mov dx,handle
  168.        call xms_func
  169.        mov result,ax
  170.      end;
  171.   end;
  172.   if result=0 then
  173.      XMS_ULock:=False
  174.   else
  175.      XMS_ULock:=True;
  176. end;
  177. {Copy XMS memory}
  178. function XMS_Copy(PT:pXMMS):Boolean;
  179. var
  180.   xoff,result:word;
  181. begin
  182.   result:=$ff;
  183.   if XMS then
  184.   begin
  185.     xoff:=Ofs(PT^);
  186.     asm
  187.       mov ah,0bh
  188.       mov si,xoff
  189.       call xms_func
  190.       mov result,ax
  191.     end;
  192.   end;
  193.   if result=0 then
  194.   begin
  195.     XMS_Copy:=False;
  196.   end else
  197.   begin
  198.     XMS_Copy:=True;
  199.   end;
  200. end;
  201. {Copy memory buffer to XMS}
  202. function XMS_CopyToXMS(DstHandle:word;lDstOffset:Pointer;pSrc:Pointer;lLen:LongInt):Boolean;
  203. begin
  204.   trans.byte_count:=llen;
  205.   trans.source_handle:=0;
  206.   trans.source_offset:=pByte(pSrc);
  207.   trans.dest_handle:=DstHandle;
  208.   trans.dest_offset:=lDstOffset;
  209.   XMS_CopyToXMS:=XMS_Copy(@trans);
  210. end;
  211. {Copy XMS to memory buffer}
  212. function XMS_CopyFromXMS(pDst:Pointer;SrcHandle:word;lSrcOffset:Pointer;lLen:LongInt):Boolean;
  213. begin
  214.   trans.byte_count:=llen;
  215.   trans.source_handle:=SrcHandle;
  216.   trans.source_offset:=lSrcOffset;
  217.   trans.dest_handle:=0;
  218.   trans.dest_offset:=pByte(pDst);
  219.   XMS_CopyFromXMS:=XMS_Copy(@trans);
  220. end;
  221. {init_unit}
  222. begin
  223.   XMS:=XMS_Init;
  224.   XMS_GetFree;
  225. end.
测试实例:100bytes数据拷贝到XMS中,程序赋值,从XMS恢复100Bytes的值。
  1. {UXMSTEST.pas}
  2. {
  3. XMS example for XMS library, copyright (C) 2008 by Favory.Peng,
  4. This example will show you how to XMS library.
  5. }
  6. program uxmstest;
  7. uses dos,crt,uxms;
  8. var
  9.   szStr:array[0..99of Byte;
  10.   i,xms_handle:word;
  11.   nStrLen:LongInt;
  12. {main}
  13. begin
  14.   clrscr;
  15.   for i:=0 to 99 do
  16.   begin
  17.     szStr[i]:=i;
  18.   end;
  19.   nStrLen:=100;
  20.   if XMS_GetFree then writeln('Free memory: Max=',max_block,' KB, total=',total_block,' KB.');
  21.   xms_handle:=XMS_Allocate(1);
  22.   if xms_handle=0 then
  23.     writeln('Allocate failed!')
  24.   else begin
  25.     writeln('Allocate 1KB memory: Handle=',xms_handle);
  26.   end;
  27.   if XMS_GetFree then writeln('Free memory: Max=',max_block,' KB, total=',total_block,' KB.');
  28.   if XMS then writeln('XMS Version: ',XMS_GetVer);
  29.   writeln('--------------------------------------------------------------------------');
  30.   for i:=0 to 99 do
  31.   begin
  32.     write(szStr[i],',');
  33.   end;
  34.   writeln;
  35.   writeln('1. Copy buffer to XMS.....   buffer size=',nStrLen);
  36.   XMS_CopyToXMS(xms_handle,Pointer(0),@szStr,nStrLen);
  37.   writeln('2. Reset buffer....');
  38.   for i:=0 to 99 do
  39.   begin
  40.     szStr[i]:=0;
  41.     write(szStr[i],',');
  42.   end;
  43.   writeln;
  44.   XMS_CopyFromXMS(@szStr,xms_handle,Pointer(0),nStrLen);
  45.   writeln('3. Restore buffer....');
  46.   for i:=0 to 99 do
  47.   begin
  48.     write(szStr[i],',');
  49.   end;
  50.   writeln;
  51.   writeln('--------------------------------------------------------------------------');
  52.   XMS_Free(xms_handle);
  53.   if XMS_GetFree then writeln('Free memory: Max=',max_block,' KB, total=',total_block,' KB.');
  54.   readkey;
  55. end.

XMS操作单元UXMS.PAS:

 

UXMS使用实例执行结果:

本文到此结束!

 

 

 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值