本篇给出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
#ifndef__XMS_H
#define __XMS_H
#define XMS_MOVEFROM0
#define XMS_MOVETO1
extern " C " {
#endif
/* 定义使用XMS内存函数 */
/* 测试XMS内存是否可用,将测试结果放在XMS_Flag,并返回XMS_Flag */
int XMS_Init( void );
/* 返回最大XMS内存块字节数 */
unsigned long XMS_GetFree( void );
/* 分配XMS内存,参数为字节数(长整型),成功返回内存块句柄,失败返回0 */
unsignedXMS_Alloc(unsigned long );
/* 释放XMS内存块,参数位内存块句柄,成功返回1,失败返回0 */
int XMS_Free(unsigned);
/* 传输数据,参数:缓冲区;XMS句柄;XMS偏移量;字节数;传输标记,成功返回1,失败返回0
传输标记:XMS_MOVEFROM从XMS中取数据到缓冲区;
XMS_MOVETO将缓冲区数据送到XMS */
int XMS_Move( void far * ,unsigned,unsigned long ,unsigned long , int );
}
#endif
#endif
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 long XMS_GetFree( void )
;
PROC_XMS_GetFree
movah, 8
call[dwordXMS_addr]
movdx,ax
shlax,0ah
shrdx,06h
ret
ENDP
;
; int XMS_Init( void );
;
PROC_XMS_Init
movax,4300h
int 02fh
cmpal,80h
jne@@ 1
movax,4310h
int 02fh
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 int XMS_Alloc( long size)
;
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
;
; int XMS_Move( void far * buf,unsigned long ofs,unsigned long bytes, int flag)
;
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
;
; int XMS_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