`
emowuyi
  • 浏览: 1470544 次
文章分类
社区版块
存档分类
最新评论

Turbo C使用的汇编函数 -- XMS内存管理函数

 
阅读更多

本篇给出XMS(扩充内存)内存TC函数汇编码文件,要使用XMS,必须安装驱动程序EMM386.EXE。注意,XMS与EMS(扩展内存)是2种不同的内存管理技术规范,由于它们对内存的管理范围有重叠,所以在驱动程序中应指明EMS的大小,如果全部1M外的内存全部都给了EMS,那么,XMS就只能管理UMB和HMA内存了,而这些内存还必须在DOS中配置才有,下面的配置保证了基本内存以外的内存全部由XMS管理:

device=himem.sys
device=emm386.exe noems
dos=high,umb

/*XMS.H*/

#ifndef__XMS_H
#define__XMS_H

#defineXMS_MOVEFROM0
#defineXMS_MOVETO1
externintXMS_Flag;/*XMS内存可使用标记,0不可使用,非0可使用*/
#ifdef__cplusplus
extern"C"{
#endif

/*定义使用XMS内存函数*/

/*测试XMS内存是否可用,将测试结果放在XMS_Flag,并返回XMS_Flag*/
intXMS_Init(void);
/*返回最大XMS内存块字节数*/
unsigned
longXMS_GetFree(void);
/*分配XMS内存,参数为字节数(长整型),成功返回内存块句柄,失败返回0*/
unsignedXMS_Alloc(unsigned
long);
/*释放XMS内存块,参数位内存块句柄,成功返回1,失败返回0*/
intXMS_Free(unsigned);
/*传输数据,参数:缓冲区;XMS句柄;XMS偏移量;字节数;传输标记,成功返回1,失败返回0
传输标记:XMS_MOVEFROM从XMS中取数据到缓冲区;
XMS_MOVETO将缓冲区数据送到XMS
*/
intXMS_Move(voidfar*,unsigned,unsignedlong,unsignedlong,int);
#ifdef__cplusplue
}
#endif

#endif

XMS.ASM

P386N
includetasm_c.inc

XMS_MOVEFROMequ
0
XMS_MOVETOequ
1

DATASEG

PUBLIC_XMS_GetFree
PUBLIC_XMS_Alloc
PUBLIC_XMS_Move
PUBLIC_XMS_Free
PUBLIC_XMS_Init
PUBLIC_XMS_Flag

XMS_addrdd
0
_XMS_Flagdw
0
;
XMS_Bytesdd
0
XMS_SouHanddw
0
XMS_SouAddrdd
0
XMS_DesHanddw
0
XMS_DesAddrdd
0
;
CODESEG
;
;unsigned
longXMS_GetFree(void)
;
PROC_XMS_GetFree

movah,
8
call[dwordXMS_addr]
movdx,ax
shlax,0ah
shrdx,06h
ret
ENDP
;
;
intXMS_Init(void);
;
PROC_XMS_Init

movax,4300h
int02fh
cmpal,80h
jne@@
1
movax,4310h
int02fh
mov[wordXMS_addr
+2],es
mov[wordXMS_addr],bx
movah,
8
call[dwordXMS_addr]
mov[word_XMS_Flag],ax
jmp
short@@2
@@
1:
mov[word_XMS_Flag],
0
xorax,ax
@@
2:
ret
ENDP
;
;unsigned
intXMS_Alloc(longsize)
;
PROC_XMS_Alloc

ARGsize:dword

movax,[_XMS_Flag]
cmpax,
0
je@@
1
moveax,[dwordsize]
addeax,3ffh
shreax,0ah
movdx,ax
movah,
9
call[dwordXMS_addr]
cmpax,
0
jz@@
1
movax,dx
@@
1:
ret
ENDP
;
;
intXMS_Move(voidfar*buf,unsignedlongofs,unsignedlongbytes,intflag)
;
PROC_XMS_Move

ARGbuf:farptr,handle:word,ofs:dword,bytes:dword,flag:word
USESsi

moveax,[dwordbytes]
mov[dwordXMS_Bytes],eax
cmp[wordflag],XMS_MOVEFROM
jne@@
1
movax,[handle]
mov[XMS_SouHand],ax
moveax,[dwordofs]
mov[XMS_SouAddr],eax
mov[wordXMS_DesHand],
0
moveax,[dwordbuf]
mov[dwordXMS_DesAddr],eax
jmp
short@@2
@@
1:
mov[wordXMS_SouHand],
0
moveax,[dwordbuf]
mov[XMS_SouAddr],eax
movax,[handle]
mov[XMS_DesHand],ax
moveax,[dwordofs]
mov[dwordXMS_DesAddr],eax
@@
2:
leasi,[XMS_Bytes]
movah,0bh
call[dwordES_XMS_addr]
ret
ENDP
;
;
intXMS_Free(handle)
;
PROC_XMS_Free

ARGhandle:word

movah,0ah
movdx,[handle]
call[dwordXMS_addr]
ret
ENDP
;
END

上面的文件中使用的插入文件tasm_c.inc和编译文件在《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)》中。本来想找个测试代码,可是代码确实太长(一个完整的程序),反正XMS函数调用也不复杂,也就免了。

连续几篇文章,将我十多年前自认为精华的代码全掏空了,从1998年,我就很少接触C/C++,虽说C/C++的代码还能看懂,也能写几句,但社会变化太快,近十年的时间不知改变了许多,有时候,我也用C/C++写点东西,但自从在Delphi版被一个自认为的C++“高手”的家伙所辱后,就没有再正二八经的用过“C++”(我其实是实话实说,说我不懂STL,也不喜欢它,他说,不懂STL就是不懂C++,当然还有他人帮腔也这么说,我只好无话可说了,原来我不用STL写的代码不能叫C++代码?!不过,偶尔也用BCB做点试验,反正BCB主要用VCL,极少用到STL)。幸好我只是个业余编程爱好者,不靠它吃饭!

再次声明,这几篇文章的代码是1995年前的东西,用现在的眼光去看它们,还不知道是不是C函数,只能供初学者们借鉴参考。至于是否有错误,我就不得而知了,不过,我以前使用时,没出过什么问题。有错误或建议,请来信:maozefa@hotmail.com

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics