| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1457 人关注过本帖
标题:XMS功能调用及源程序(最全)
只看楼主 加入收藏
ba_wang_mao
Rank: 2
来 自:成都理工大学
等 级:论坛游民
帖 子:297
专家分:27
注 册:2006-11-7
收藏
 问题点数:0 回复次数:2 
XMS功能调用及源程序(最全)

XMS功能调用索引表
XMS功能号 功能
功能00H 取XMS版本号
功能01H 请求高内存区HMA
功能02H 释放高内存区HMA
功能03H 全程启用A20
功能04H 全程停用A20
功能05H 局部启用A20
功能06H 局部停用A20
功能07H 查询A20状态
功能08H 查询自由扩展内存
功能09H 分配扩展内存块
功能0AH 释放扩展内存块
功能0BH 移动扩展内存块
功能0CH 锁住扩展内存块
功能0DH 扩展内存块解锁
功能0EH 取EMB句柄信息
功能0FH 重新分配扩展内存块
功能10H 请求上位存储块UMB
功能11H 释放上位存储块UMB
1. 测试xms是否存在
使用中断2fH的43H(AH)功能的00H(AL)子功能,可以获得是否安装了XMS驱动程序的信息,如果AL返回为80H则说明XMS安装了。以下给出具体函数:
char test_xms()
{
asm {
mov ax,0x4300
int 0x2f
}
if (_AL==0x80)
XMS=1;
return(XMS);
}
2. 获取xms驱动程序入口地址
使用中断2fH的43H(AH)功能的10H(AL)子功能,可以获得xms驱动程序入口地址,返回的ES:BX便是具体的入口。以下给出具体函数:
void get_driver_address()
{
if (XMS) {
asm {
mov ax,0x4310 //功能号43H
int 0x2f //调用中断2fH
}
xms=(void (far *)())(((long)(_ES)<<16)+_BX);//取到指向xms服务函数的指针
}
}
3. 获取XMS版本号
在获得XMS驱动程序入口地址之后,我们可以根据XMS驱动程序提供的功能号来调用具体的XMS功能,使用功能00H(AH)可以获得XMS的版本信息,AX返回XMS版本号,BX返回内部修订版本。
void get_xms_version(unsigned *xms_ver,unsigned *int_ver)
{
if (XMS) {
asm mov ah,0x00//取得功能号
xms();//调用XMS驱动程序
*xms_ver=_AX;//返回xms版本号
*int_ver=_BX;//返回内部修订本
HMA=_DX;
}
}
4. 请求分配高端内存(High Memory Area)
使用功能01H(AH)可以请求分配高端内存,同时DX给入要分配的内存字节数,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
char Request_HMA(unsigned size)
{
char error_code=0xff;
if (XMS) {
asm {
mov ah,0x01
mov dx,size
}
xms();
error_code=_BL;
}
return(error_code);
}
5. 释放高端内存
使用功能02H(AH)可以释放高端内存,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
char Release_HMA()
{
char error_code=0xff;
if (XMS) {
asm mov ah,0x02
xms();
error_code=_BL;
}
return(error_code);
}
6. 全程激活A20地址线
使用功能03H(AH)可以全程激活A20地址线,用于使用HMA,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
char global_enable_A20()
{
char error_code=0xff;
if (XMS) {
asm mov ah,0x03
xms();
error_code=_BL;
}
return(error_code);
}
7. 全程关闭A20地址线
使用功能04H(AH)可以全程关闭A20地址线,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
char global_disable_A20()
{
char error_code=0xff;
if (XMS) {
asm mov ah,0x04
xms();
error_code=_BL;
}
return(error_code);
}
8. 局部激活A20地址线
使用功能05H(AH)可以局部激活A20地址线, 用于直接访问扩充内存,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
char local_enable_A20()
{
char error_code=0xff;
if (XMS) {
asm mov ah,0x05
xms();
error_code=_BL;
}
return(error_code);
}
9. 局部关闭A20地址线
使用功能06H(AH)可以局部关闭A20地址线,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
char local_disable_A20()
{
char error_code=0xff;
if (XMS) {
asm mov ah,0x06
xms();
error_code=_BL;
}
return(error_code);
}
10. 查询A20地址线状态
使用功能07H(AH)可以查询A20地址线当前处于激活还是关闭状态,AX返回0001H表示激活、0000H表示关闭,失败时BL返回错误代码,以下给出具体函数:
char query_A20_state(unsigned *state){
char error_code=0xff;
if (XMS) {
asm mov ah,0x07
xms();
*state=_AX;//返回a20地址线状态
error_code=_BL;
}
return(error_code);
}
11. 查询空闲的扩充内存空间
使用功能08H(AH)可以查询空闲的扩充内存空间, 不包括HMA,AX返回最大的扩充内存块的大小(单位:K),DX返回总的扩充内存块的大小(单位:K),失败时BL返回错误代码。
char query_free_xms(unsigned *max_block,unsigned *total)
{
char error_code=0xff;
if (XMS) {
asm mov ah,0x08
xms();
*max_block=_AX;//返回最大的扩充内存块的大小
*total=_DX;// 返回总的扩充内存块的大小
error_code=_BL;
}
return(error_code);
}
12. 分配扩充内存
使用功能09H(AH)可以分配扩充内存,DX给入要求分配的内存块大小(单位:K),AX返回0001H表示成功、0000H表示失败,DX返回内存块的句柄,失败时BL返回错误代码,以下给出具体函数:
char allocate_xms(unsigned size,unsigned *handle)
{
char error_code=0xff;
if (XMS) {
asm {
mov ah,0x09
mov dx,size
}
xms();
*handle=_DX;//返回句柄
error_code=_BL;
}
return(error_code);
}
13. 释放指定句柄所分配的扩充内存
使用功能0AH(AH)可以释放指定句柄所分配的扩充内存,DX给入内存块的句柄,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
char free_xms(unsigned handle)
{
char error_code=0xff;
if (XMS) {
asm {
mov ah,0x0a
mov dx,handle
}
xms();
error_code=_BL;
}
return(error_code);
}
14. 移动扩充内存块
使用功能0BH(AH)可以移动扩充内存块,DS:SI给入xms_mov结构,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
typedef struct xms_mov {
unsigned long byte_count; // 移动的字节数
unsigned source_handle; // 源句柄
unsigned long source_offset; // 源偏移量
unsigned destination_handle; // 目的句柄
unsigned long destination_offset; // 目的偏移量
} xmm;

char move_xms(xmm *xmm_ptr)
{
char error_code=0xff;
if (XMS) {
unsigned xseg=FP_SEG(xmm_ptr),xoff=FP_OFF(xmm_ptr);
asm {
mov ah,0x0b
mov si,xoff
mov ds,xseg
}
xms();
error_code=_BL;
}
return(error_code);
}
15. 锁定指定的句柄所分配的扩充内存块
使用功能0CH(AH)可以锁定指定的句柄所分配的扩充内存块,DX给入句柄,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
char lock_XMS_block(unsigned handle)
{
char error_code=0xff;
if (XMS) {
asm {
mov ah,0x0c
mov dx,handle
}
xms();
error_code=_BL;
}
return(error_code);
}
16. 解锁指定的句柄所分配的扩充内存块
使用功能0DH(AH)可以解锁指定的句柄所分配的扩充内存块,DX给入句柄,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
char unlock_XMS_block(unsigned handle)
{
char error_code=0xff;
if (XMS) {
asm {
mov ah,0x0d
mov dx,handle
}
xms();
error_code=_BL;
}
return(error_code);
}
17. 获取描写句柄的信息
使用功能0EH(AH)可以获取描写句柄的信息,DX给入句柄,AX返回0001H表示成功、0000H表示失败,BH返回块锁定计数值,BL返回可用的句柄,DX返回句柄分配的块的容量(单位:K),失败时BL返回错误代码,以下给出具体函数:
typedef struct XMS_handle_info {
unsigned char lock_count; // 块锁定计数值
unsigned char free_handle; // 可用的句柄
unsigned size; // 句柄分配的块的容量(单位:K)
} xhi;
char get_handle_info(unsigned handle,xhi *handle_info)
{
char error_code=0xff;
if (XMS)
{
asm {
mov ah,0x0e
mov dx,handle
}
xms();
error_code=_BL;
handle_info->lock_count=_BH;
handle_info->free_handle=_BL; //获取可用的句柄
handle_info->size=_DX; //获取句柄分配的块的容量
}
return(error_code);
}
18. 为句柄重新分配内存
使用功能0FH(AH)可以为句柄重新分配内存,DX给入句柄,BX给入新的块的容量(单位:K),AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码,以下给出具体函数:
char reallocate_xms_block(unsigned handle,unsigned size)
{
char error_code=0xff;
if (XMS) {
asm {
mov ah,0x0f
mov dx,handle
mov bx,size
}
xms();
error_code=_BL;
}
return(error_code);
}
19. 请求分配UMB
使用功能10H(AH)可以请求分配UMB(upper memory block,即上位内存, 640K以上的非EMS内存),DX给入块的大小(单位:节, 即paragraphs, 为16个字节),AX返回0001H表示成功、0000H表示失败,BX返回分配UMB的段地址,DX返回块的实际容量actual size of block,失败时BL返回错误代码,以下给出具体函数:
typedef struct UMB_info {
unsigned UMB_segment;
unsigned size;
} ui;
char request_UMB(unsigned size,ui *info)
{
char error_code=0xff;
if (XMS) {
asm {
mov ah,0x10
mov dx,size
}
xms();
error_code=_BL;
info->UMB_segment=_BX;//返回umb段地址
info->size=_DX;//返回容量
}
return(error_code);
}
20. 释放UMB
使用功能11H(AH)可以释放UMB(upper memory block),640K以上的非EMS内存),DX给入要释放的UMB内存的段地址,AX返回0001H表示成功、0000H表示失败,失败时BL返回错误代码。
char release_UMB(unsigned segment)
{
char error_code=0xff;
if (XMS) {
asm {
mov ah,0x10
mov dx,segment
}
xms();
error_code=_BL;
}
return(error_code);
}
这里值得一提的是HIMEM.SYS需要至少为256字节的栈空间。此外给出错误时BL返回的错误代码及其含义:
80h 没有提供的功能
81h 检测到虚拟盘(Vdisk)
82h 发生A20地址线错误
8Eh 一般驱动程序错误
8Fh 致命的驱动程序错误
90h 高端内存(HMA)不存在
91h 高端内存(HMA)已被使用
92h DX is less than the /H MAMIN = parameter
93h 高端内存(HMA)未被分配
94h A20地址线已被激活
A0h 所有扩充内存已被分配
A1h 所有可用的句柄已被分配
A2h 无效的句柄
A3h 无效的源句柄
A4h 无效的源偏移
A5h 无效的目的句柄
A6h 无效的目的偏移
A7h 无效的长度
A8h 移动有非法的重叠
A9h 发生奇偶校验错误
AAh 块未加锁
ABh 块已被锁定
ACh 块锁定计数溢出
ADh 锁定失败
B0h 只有更小一些的UMB空间
B1h 没有可用的UMB空间

搜索更多相关主题的帖子: XMS功能 内存 HMA 局部 
2006-12-21 19:18
jig
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
帖 子:530
专家分:242
注 册:2005-12-27
收藏
得分:0 
不错,支持

个人网站 -  http://.h001.
2006-12-21 19:40
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
DOS实模式下的图形编程的确常会用到,要是能将代码中的嵌入汇编改成C就好了,那几段代码很简单,没有用汇编的必要。
2006-12-23 09:44
快速回复:XMS功能调用及源程序(最全)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019988 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved