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

#define     XMS_MOVEFROM    0
#define     XMS_MOVETO    1
extern   int  XMS_Flag;         /*  XMS 内存可使用标记, 0 不可使用, 非 0 可使用  */
#ifdef    __cplusplus
extern   " C "  {
#endif

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

/*  测试 XMS 内存是否可用, 将测试结果放在 XMS_Flag, 并返回 XMS_Flag  */
int  XMS_Init( void );
/*  返回最大 XMS 内存块字节数  */
unsigned 
long  XMS_GetFree( void );
/*  分配 XMS 内存, 参数为字节数(长整型), 成功返回内存块句柄, 失败返回 0  */
unsigned XMS_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 );
#ifdef    __cplusplue
}
#endif

#endif

 

    XMS.ASM

    P386N
    include        tasm_c.inc

XMS_MOVEFROM    equ    
0
XMS_MOVETO    equ    
1

    DATASEG

    PUBLIC    _XMS_GetFree
    PUBLIC    _XMS_Alloc
    PUBLIC    _XMS_Move
    PUBLIC    _XMS_Free
    PUBLIC    _XMS_Init
    PUBLIC    _XMS_Flag

XMS_addr    dd    
0
_XMS_Flag    dw    
0
;
XMS_Bytes    dd    
0
XMS_SouHand    dw    
0
XMS_SouAddr    dd    
0
XMS_DesHand    dw    
0
XMS_DesAddr    dd    
0
;
        CODESEG
;
; unsigned 
long  XMS_GetFree( void )
;
PROC    _XMS_GetFree

    mov    ah, 
8
    call    [dword XMS_addr]
    mov    dx, ax
    shl    ax, 0ah
    shr    dx, 06h
    ret
ENDP
;
int  XMS_Init( void );
;
PROC    _XMS_Init

    mov    ax, 4300h
    
int     02fh
    cmp    al, 80h
    jne    @@
1
    mov    ax, 4310h
    
int     02fh
    mov    [word XMS_addr
+ 2 ], es
    mov    [word XMS_addr], bx
    mov    ah, 
8
    call    [dword XMS_addr]
    mov    [word _XMS_Flag], ax
    jmp    
short  @@ 2
@@
1 :
    mov    [word _XMS_Flag], 
0
    xor    ax, ax
@@
2 :
    ret
ENDP
;
; unsigned 
int  XMS_Alloc( long  size)
;
PROC    _XMS_Alloc

    ARG    size : dword

    mov    ax, [_XMS_Flag]
    cmp    ax, 
0
    je    @@
1
    mov     eax, [dword size]
    add    eax, 3ffh
    shr    eax, 0ah
    mov    dx, ax
    mov    ah, 
9
    call    [dword XMS_addr]
    cmp    ax, 
0
    jz    @@
1
    mov    ax, dx
@@
1 :
    ret
ENDP
;
int  XMS_Move( void  far  * buf, unsigned  long  ofs, unsigned  long  bytes,  int  flag)
;
PROC    _XMS_Move

    ARG    buf : far ptr, handle : word, ofs : dword, bytes : dword, flag : word
    USES    si

    mov    eax, [dword bytes]
    mov    [dword XMS_Bytes], eax
    cmp    [word flag], XMS_MOVEFROM
    jne    @@
1
    mov    ax, [handle]
    mov    [XMS_SouHand], ax
    mov    eax, [dword ofs]
    mov    [XMS_SouAddr], eax
    mov    [word XMS_DesHand], 
0
    mov    eax, [dword buf]
    mov    [dword XMS_DesAddr], eax
    jmp    
short  @@ 2
@@
1 :
    mov    [word XMS_SouHand], 
0
    mov    eax, [dword buf]
    mov    [XMS_SouAddr], eax
    mov    ax, [handle]
    mov    [XMS_DesHand], ax
    mov    eax, [dword ofs]
    mov    [dword XMS_DesAddr], eax
@@
2 :
    lea    si, [XMS_Bytes]
    mov    ah, 0bh
    call    [dword ES_ XMS_addr]
    ret
ENDP
;
int  XMS_Free(handle)
;
PROC    _XMS_Free

    ARG     handle : word

    mov    ah, 0ah
    mov    dx, [handle]
    call    [dword XMS_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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值