本来我是不准备写这篇文章的,但冷不妨有位同仁问起,也只好做个回答,顺便借此更新一下网页。
XMS,扩充内存管理规范。在16bit DOS系统下,为了使用640k以外的内存,XMS成了一种最好的手法。
在这里,我不想多讲XMS的实现,只对本文所提供的XMS类做一下使用讲解。
例子可以说明一切:
#include”XMS.H”
void main()
{
FILE *fp;
int i;
char *str;
XMS xms1(1024); //为xms1指针分配1024k的内存
fp=fopen(“C:\\WIN\\WIN386.SWP”,”rb”);
str=(char *)malloc(1024);
for(i=0;i<1024;i++)
{
fread(str,1,1024,fp);
xms1.put((void *)str,(void *)(i*1024),1024);
//将内存指针str中的1024个字节的内容写到,xms1的第i*1024个字节处
}
fclose(fp);
fp=fopen(“WIN386.SWP”,”wb”);
for(i=0;i<1024;i++)
{
xms1.get((void *)str,(void *)(i*1024),1024);
//将扩充内存xms1中,从第i*1024个字节处开始的1024个字节的内容写到str中
fwrite(str,1,1024,fp);
}
fclose(fp);
}
XMS.H
#if !defined XMS_H
#define XMS_H
class XMS {
int handle;
int move(struct EMB *emb);
public:
XMS(int size);
~XMS();
static int OK;
static int init(void);
static unsigned freesize(void);
static unsigned largestblock(void);
int realloc(int size);
int put(void *dp,void *sp,long leng);
int get(void *dp,void *sp,long leng);
};
#endif
XMS.CPP
#include <dos.h>
#include <alloc.h>
#include “xms.h”
struct EMB {
long Leng;
unsigned SourceHandle;
long SourceOfs;
unsigned DestinHandle;
long DestinOfs;
};
int XMS::OK=0;
static void far *XMSaddr;
int XMS::init(void)
{
static struct REGPACK rg;
rg.r_ax=0x4300;
intr(0x2f,&rg);
if( (rg.r_ax&0x00ff) == 0x80 )
{
rg.r_ax=0x4310;
intr(0x2f,&rg);
XMSaddr=MK_FP(rg.r_es,rg.r_bx);
OK=1;
}
else
OK=0;
return(OK);
}
unsigned XMS::freesize(void)
{
if(OK==0)
return(0);
asm {
mov ah,8
call XMSaddr
}
return _DX;
}
unsigned XMS::largestblock(void)
{
if(OK==0)
return(0);
asm {
mov ah,8
call XMSaddr
}
return _AX;
}
XMS::XMS(int size)
{
if(OK==0)
{
handle=0;
return;
}
asm {
mov ah,9
mov dx,size
call XMSaddr
}
handle=_DX;
}
XMS::~XMS()
{
if(handle==0)
return;
int hd=handle;
asm {
mov ah,0ah
mov dx,hd
call XMSaddr
}
}
int XMS::realloc(int size)
{
if(handle==0)
return(0);
int hd=handle;
asm {
mov ah,0fh
mov bx,size
mov dx,hd
call XMSaddr
}
return _AX;
}
int XMS::move(struct EMB *emb)
{
asm {
push ds
mov ah,0bh
push ds
pop es
lds si,emb
call es:XMSaddr
pop ds
}
return _AX;
}
int XMS::put(void *sp,void *dp,long leng)
{
struct EMB emb;
if(leng&1L)
leng++;
emb.Leng=leng;
emb.SourceHandle=0;
emb.SourceOfs=(long)sp;
emb.DestinHandle=handle;
emb.DestinOfs=(long)dp;
return move(&emb);
}
int XMS::get(void *dp,void *sp,long leng)
{
int v;
struct EMB emb;
if(leng&1L)
{
char *p,*d;
leng–;
if( leng>0 )
{
emb.Leng=leng;
emb.SourceHandle=handle;
emb.SourceOfs=(long)sp;
emb.DestinHandle=0;
emb.DestinOfs=(long)dp;
move(&emb);
}
p=(char *)malloc(2);
emb.Leng=2L;
emb.SourceHandle=handle;
emb.SourceOfs=(long)sp+leng;
emb.DestinHandle=0;
emb.DestinOfs=(long)p;
v=move(&emb);
d=(char*)dp;
d[leng]=p[0];
free(p);
}
else
{
emb.Leng=leng;
emb.SourceHandle=handle;
emb.SourceOfs=(long)sp;
emb.DestinHandle=0;
emb.DestinOfs=(long)dp;
v=move(&emb);
}
return(v);
}