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

EMS功能调用索引
功能号 功能
功能40H 取得EMS程序状态
功能41H 取得物理映射页面的段地址
功能42H 获取逻辑页页数信息
功能43H 分配句柄和内存
功能44H 内存映射
功能45H 释放句柄和内存
功能46H 获取EMM的版本号
功能47H 保存指定句柄映射关系
功能48H 恢复指定句柄映射关系
功能4BH 获取EMM的句柄数
功能4CH 获取指定句柄所分配的逻辑页页数
功能4DH 获取所有句柄分配情况
1. 测试EMS管理程序
测试EMS管理程序, 找到返回1, 否则返回0,以下给出具体函数:
char test_ems() {
int i;
union REGS inregs,outregs;
struct SREGS segs;
struct DeviceHeader {
struct DeviceHeader far *link;
unsigned attributes;
unsigned strategy_offset;
unsigned interrupt_offset;
char name_of_number_of_units[8];
}far *dev;
unsigned char major,minor,c[13];

inregs.x.ax=0x3001;//dos中断功能30子功能01读取当前扩充内存是否有效
intdos(&inregs,&outregs);//DOS中断
major=outregs.h.al;//返回扩充内存状态
minor=outregs.h.ah;
if (major<2)
return(0);//扩充内存无效
else
{
inregs.h.ah=0x52;//dos中断功能52返回计算机内存中启用服务设备名称链表
intdosx(&inregs,&outregs,&segs);//dos中断
if (major==2)//获得设备起始地址
dev=(struct DeviceHeader far *)MK_FP(segs.es+1,outregs.x.bx+7);
else if ((major==3) && (minor==0))
dev=(struct DeviceHeader far *)MK_FP(segs.es+2,outregs.x.bx+8);
else
dev=(struct DeviceHeader far *)MK_FP(segs.es+2,outregs.x.bx+2);
c[8]=NULL;
while (FP_OFF(dev)!=0xffff)
{//直到设备全部被检测
if (dev->attributes & 0x8000)
{
for (i=0;i<8;i++)//名称长度8位
c[i]=dev->name_of_number_of_units[i];
}//取设备名称
if (!strcmp(c,"EMMXXXX0"))
{ //将设备名称与扩充内存名字比较
EMS=1;//扩充内存存在
return(1);
}
dev=dev->link;
}//指向下一个设备
}
return(0);
}
2. 取得管理程序状态
在确认EMS存在时,使用中断67H功能40H(AH)可以取得管理程序状态,AH返回00H表示成功、否则返回错误代码。以下给出具体函数:
char get_EMS_status()
{
char tmp=0xff;
if (EMS)
{
asm {
mov ah,0x40//功能号40h
int 0x67//调用中断67h
mov tmp,ah//返回值
}
}
return(tmp);
}
3. 取得物理映射页面的段地址
使用中断67H功能41H(AH)可以取得物理映射页面的段地址,AH返回00H表示成功、否则返回错误代码,BX返回物理映射页面的段地址。使用此功能可确定EMS在1Mb常规内存中的映射位置,此物理映射页面的大小为64K, 分为0-3页, 每页为16K,因为EMS逻辑页的大小为16K, 也就是说我们最多可同时将4个EMS逻辑页映射到物理页上。以下给出具体函数:
char get_page_frame_segment(unsigned *segment)
{
char tmp=0xff;
if (EMS) {
asm {
mov ah,0x41
int 0x67
mov tmp,ah
}
*segment=_BX;//取得段地址
}
return(tmp);
}
4. 获取逻辑页页数信息
使用中断67H功能42H(AH)可以获取逻辑页页数信息,AH返回00H表示成功、否则返回错误代码,BX返回未分配的页数,DX返回页的总数。以下给出具体函数:
char get_number_of_pages(unsigned *avail,unsigned *total)
{
char tmp=0xff;
if (EMS) {
asm {
mov ah,0x42
int 0x67
mov tmp,ah
}
*avail=_BX;//返回可用页数
*total=_DX;//返回所有页数
}
return(tmp);
}
5. 分配句柄和内存
使用中断67H功能43H(AH)可以分配句柄和内存,BX给入要求分配的逻辑页的页数(逻辑页每页的大小为16K),AH返回00H表示成功、否则返回错误代码,DX返回句柄。当程序退出运行时, 句柄将被非显式的关闭并无法回收。以下给出具体函数:
char allocate_memory(unsigned *handle,unsigned page_numbers)
{
char tmp=0xff;
if (EMS) {
asm {
mov ah,0x43
mov bx,page_numbers
int 0x67
mov tmp,ah
}
*handle=_DX;//返回句柄
}
return(tmp);
}
6. 内存映射
使用中断67H功能44H(AH)可以进行内存映射,AL给入物理页页号 (0-3),BX给入要求分配的逻辑页的页数(逻辑页每页的大小为16K),DX给入句柄,AH返回00H表示成功、否则返回错误代码。char map_memory(char physical_page,unsigned logical_page,unsigned handle)
{
char tmp=0xff;
if (EMS) {
asm {
mov ah,0x44
mov al,physical_page //物理页数
mov bx,logical_page //逻辑页数
mov dx,handle
int 0x67
mov tmp,ah
}
}
return(tmp);
}
7. 释放句柄和内存
使用中断67H功能45H(AH)可以释放句柄和内存,DX给入EMM句柄,AH返回00H表示成功、否则返回错误代码。句柄必须被显示的释放, 否则分配的内存无法被其后的程序使用。如果不成功, 应重试这一操作。以下给出具体函数:
char release_memory(unsigned handle)
{
char tmp=0xff;
if (EMS) {
asm {
mov ah,0x45
mov dx,handle
int 0x67
mov tmp,ah
}
}
return(tmp);
}
8. 获取EMM的版本号
使用中断67H功能46H(AH)可以获取EMM的版本号,AH返回00H表示成功、否则返回错误代码,AL返回EMM的版本号,高四位为主版本号(BCD码),低四位为副版本号(BCD码)。句柄必须被显示的释放, 否则分配的内存无法被其后的程序使用。如果不成功, 应重试这一操作。
char get_EMM_version(unsigned char *version)
{
char tmp=0xff;
if (EMS) {
asm {
mov ah,0x46
int 0x67
mov tmp,ah
}
*version=_AL;
}
return(tmp);
}
9. 保存指定句柄映射关系
使用中断67H功能47H(AH)可以保存指定句柄映射关系,DX给入句柄,AH返回00H表示成功、否则返回错误代码。一些TSR, ISR或设备驱动程序要使用EMS, 必须在操作前保存映射关系并在完成后恢复。以下给出具体函数:
char save_mapping_context(unsigned handle)
{
char tmp=0xff;
if (EMS) {
asm {
mov ah,0x47
mov dx,handle
int 0x67
mov tmp,ah
}
}
return(tmp);
}
10. 恢复指定句柄映射关系
使用中断67H功能48H(AH)可以恢复指定句柄映射关系,DX给入句柄,AH返回00H表示成功、否则返回错误代码。一些TSR, ISR或设备驱动程序要使用EMS, 必须在操作前保存映射关系并在完成后恢复。一些TSR, ISR或设备驱动程序要使用EMS, 必须在操作前保存映射关系并在完成后恢复。char restore_mapping_context(unsigned handle)
{
char tmp=0xff;
if (EMS)
{
asm {
mov ah,0x48
mov dx,handle
int 0x67
mov tmp,ah
}
}
return(tmp);
}
获取EMM的句柄数
使用中断67H功能4BH(AH)可以获取EMM的句柄数,AH返回00H表示成功、否则返回错误代码,BX返回EMM的句柄数(0-255)。要确定可用的句柄数, 用255减去BX的值即可。以下给出具体函数:
char get_number_of_EMM_handles(unsigned *handle_numbers)

搜索更多相关主题的帖子: EMS 
2006-12-21 19:19
hjj1123
Rank: 1
等 级:新手上路
帖 子:198
专家分:0
注 册:2006-7-29
收藏
得分:0 

不错


qq:674940174
2006-12-21 19:29
jig
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
帖 子:530
专家分:242
注 册:2005-12-27
收藏
得分:0 

厉害


个人网站 -  http://.h001.
2006-12-21 19:39
tco1992
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2011-6-14
收藏
得分:0 
感谢楼主提供~分享
2011-06-29 10:57
快速回复:EMS功能调用及源程序(最全)
数据加载中...
 
   



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

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