社区
汇编语言
帖子详情
在TSR的驻留程序中可否调用DOS 21H?
Tice
2000-07-30 08:08:00
在TSR的驻留程序中可否调用DOS 21H?可以进行文件读写操作?怎样才能做到?
...全文
191
4
打赏
收藏
在TSR的驻留程序中可否调用DOS 21H?
在TSR的驻留程序中可否调用DOS 21H?可以进行文件读写操作?怎样才能做到?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
4 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
noicy
2000-09-03
打赏
举报
回复
把清华出的操作系统原理DOS篇看一遍,DOS下TSR的问题就没有可以被难得到的.
「已注销」
2000-08-05
打赏
举报
回复
TSR程序中"保存","恢复"技术的应用
TSR编程常常要遇到DOS重入,屏幕保护等许多烦人的事情.但只要采用适当的
方法,这些事情可以变得很轻松.
我的经验就是:保存!--尽情破坏--恢复!!
只要把一切可能被TSR破坏的东西(数据,硬件状态等)保存好,TSR内部就不必
再顾虑重重了.到TSR退出激活态时,把所有东西一一复原,被中断的程序就可以
安全地运行下去.
保存CPU的寄存器就不必说了,因为用interrupt关键字说明的函数会自动保存
所有寄存器.下面主要给出保存屏幕,鼠标,DOS数据等的例子.
以下的一些程序片断,仅供分析借鉴,如有不妥或需要补充的,敬请提出. :)
>>-=============================程序实例:BEGIN=============================-<<
/* 程序在Borland C++ 3.1下编译通过,由于涉及行内汇编,其他编译器产
生的结果可能有所不同,还望注意检查. */
/* 由于程序涉及较多未公开的DOS调用和内部数据结构,以及较多VGA寄存
器操作,对运行环境可能有一定的要求. */
#include <dos.h>
#include <bios.h>
#include <stdio.h>
#include <string.h>
/**************************下面是本程序的一些数据定义************************/
const unsigned PSP_ENV=0x2c; //PSP中保存环境段段址的偏移
const unsigned PSP_DTA=0x80; //PSP中用于磁盘传输区DTA的内存区首址
const unsigned long VGA_VRAMG=0xa0000000L; //图形模式显存地址首址
const unsigned long VGA_VRAMT=0xb8000000L; //文本模式显存地址首址
static char vga_buf1[2048]; //保存VGA状态数据
static char vga_buf2[0x3000]; //保存显存数据2K+2K+8K
stactic chat mouse_buf[1024]; //保存鼠标驱动程序状态数据
static char sda_buf[2048]; //保存DOS的SDA数据
//以上预先分配了一些缓冲区,其大小是经验值
static void far* sda_addr; //DOS的SDA数据区首址
static unsigned sda_size; //DOS的SDA数据区大小
static void far* indos_addr; //DOS的INDOS标志地址
//以上是DOS的一些参数,必须由main()在驻留前取得
/**************************上面是本程序的一些数据定义************************/
/************************下面是几个有关VGA操作的辅助函数*********************/
inline void vga_set_mode(unsigned modenum) //把VGA显示模式设置为modenum
{
_AX=modenum;
_AH=0x0;
geninterrupt(0x10); //AH=0,AL=modenum,调用BIOS INT 10H
}
inline void vga_rplane_sel(char planenum) //选中VGA页面planenum读取
{
_AH=planenum; //AH=planenum将被送到I/O地址0x3cf
_AL=0x4; //AL=4送0x3ce,选中"读页面选择寄存器"
outport(0x3ce,_AX); //AL先送0x3ce,AH后送0x3cf
}
inline void vga_wplane_sel(char planenum) //选中VGA页面planenum写入
{
_AX=0x0102; //AL=2送0x3c4,选中"彩色页面写允许寄存器"
_AH<<=planenum; //AH=(0x01<<planenum)将被送到I/O地址0x3c5
outport(0x3c4,_AX); //AL先送0x3c4,AH后送0x3c5
}
/***********************上面是几个有关VGA操作的辅助函数**********************/
/************************下面是几个保存和恢复屏幕的函数**********************/
/* 由于使用了VESA调用,对Super VGA的模式也可以成功地保存和恢复.
但相应地,显示卡也必须支持有关VESA调用 */
void vga_save(char far* buffer1,char far* buffer2)
//保存VGA状态到buffer1,保存被文本模式03H破坏的显存到buffer2,并切换到模式03H
{
_ES=FP_SEG(buffer1);
_BX=FP_OFF(buffer1); //ES:BX=buffer1,缓冲区的首址
_AX=0x4f04; //BIOS INT 10H的4F04号VESA功能调用
_CX=0xffff; //表示要保存所有的状态数据
_DL=0x1; //子功能1,保存VGA状态到ES:BX
geninterrupt(0x10);
vga_set_mode(0x92); //切换到模式12H,0x92的最高位是1表示保留显存数据
vga_rplane_sel(0x2); //选择页面2读取
_fmemcpy(buffer2,(void far*)VGA_VRAMG,0x2000);
//页面2的开头8K将被模式03H的字模覆盖,故保存到buffer2
vga_set_mode(0x83); //切换到模式03H,0x82的最高位是1表示保留显存数据
_fmemcpy(buffer2+0x2000,(void far*)VGA_VRAMT,0x1000);
//显存头上的4K(页面0的2K是字符,页面1的2K是属性,CPU地址交替)
//将被模式03H的屏幕数据覆盖,故保存到buffer2+0x2000
}
void vga_restore(char far* buffer1,char far* buffer2)
//用buffer2的数据恢复显存,用buffer1的数据恢复VGA状态
{
_fmemcpy((void far*)VGA_VRAMT,buffer2+0x2000,0x1000);
//恢复显存头上的4K(页面0开头的2K,页面1开头的2K)
vga_set_mode(0x92);
vga_wplane_sel(0x2);
_fmemcpy((void far*)VGA_VRAMG,buffer2,0x2000);
//恢复显存页面2的开头8K
_ES=FP_SEG(buffer1);
_BX=FP_OFF(buffer1);
_AX=0x4f04;
_CX=0xffff;
_DL=0x2; //子功能2,用ES:BX的数据恢复VGA状态
geninterrupt(0x10);
}
/************************上面是几个保存和恢复屏幕的函数**********************/
/************************下面是几个保存和恢复鼠标的函数**********************/
void mouse_save(char far* buffer) //保存鼠标驱动程序状态到buffer
{ //Warning:Inline keyword will cause an error
_ES=FP_SEG(buffer);
_DX=FP_OFF(buffer);
_AX=0x0016; //子功能0x16,保存保存鼠标驱动程序状态到ES:DX
geninterrupt(0x33); //鼠标驱动程序INT 33H服务
}
void mouse_restore(char far* buffer) //用buffer数据恢复鼠标驱动程序状态
{
_AX=0x0000;
geninterrupt(0x33); //先调子功能0x00,RESET鼠标驱动程序
_ES=FP_SEG(buffer);
_DX=FP_OFF(buffer);
_AX=0x0017; //子功能0x17,用ES:DX数据恢复鼠标驱动程序状态
geninterrupt(0x33); //鼠标驱动程序INT 33H服务
}
/************************上面是几个保存和恢复鼠标的函数**********************/
/**************************下面是有关设置DOS数据的函数***********************/
inline void set_psp(unsigned newpsp) //把DOS当前进程的PSP强行设置为newpsp
{
_BX=newpsp; //未公开的DOS调用0x50
_AH=0x50;
geninterrupt(0x21);
}
void set_dta(void far* newdta) //用newdta作为DOS磁盘传输区(DTA)
{
asm{
push ds;
lds dx,newdta; //DS:DX=newdta
mov ah,0x1a; //INT 21H的1A号功能,把DTA指向DS:DX
int 0x21;
pop ds;
}
}
/**************************上面是有关设置DOS数据的函数***********************/
/*****************下面是一个TSR激活时保存和恢复各种数据的实例****************/
void activate_tsr()
{
_fmemcpy(sda_buf,sda_addr,sda_size); //保存DOS的SDA数据区.
//SDA就是DOS的"数据段",包含了几乎所有DOS的内部数据,包括三个
// 内部堆栈,当前进程的PSP,INDOS标志,关键出错标志......
//所以用保存和恢复SDA的办法就完全不必担心DOS重入了,在tsr_body()
// 里可以随意进行DOS调用
mouse_save(mouse_buf); //保存鼠标
vga_save(vga_buf1,vga_buf2); //保存屏幕
set_psp(_psp); //把TSR自己的PSP设为DOS当前进程
set_dta(MK_FP(_psp,PSP_DTA)); //把TSR自己的DTA设为DOS当前DTA
*(char far*)indos_addr=0; //强制把INDOS标志清0
*(char far*)sda_addr=0; //强制把DOS关键出错标志(恰在SDA的偏移0处)清0
tsr_body(); //做你想做的 :DD
vga_restore(vga_buf1,vga_buf2); //恢复屏幕
mouse_restore(mouse_buf); //恢复鼠标
_fmemcpy(sda_addr,sda_buf,sda_size); //恢复SDA
}
main() //仅仅是个简易版,用来说明怎样获取sda_size,sda_addr,indos_addr
{
//这里省略了一些重要事务...
asm push ds;
asm mov ax,0x5d06;
asm int 0x21; //INT 21H的功能5D06H,返回SDA的地址送DS:SI,大小送CX
asm pop ds;
sda_size=_CX;
sda_addr=MK_FP(_BX,_SI);
//结果存入sda_addr和sda_size
asm mov ah,0x34;
asm int 0x21; //INT 21H的功能34H,返回INDOS标志的地址送ES:BX
indos_addr=MK_FP(_ES,_BX);
//结果存入indos_addr
_ES=*(unsigned far*)MK_FP(_psp,PSP_ENV);
asm mov ah,0x49;
asm int 0x21; //释放环境段所占的内存
//这里省略了一些重要事务...
}
/*****************上面是一个TSR激活时保存和恢复各种数据的实例****************/
Areslee
2000-07-31
打赏
举报
回复
如果其他程序正在调INT 21H时而你又确实也要调它,那此时你可以将DOS的临界区保存起来,
再调用INT 21H,完成后再恢复过去,这样也可以实现DOS的重入
lty
2000-07-31
打赏
举报
回复
当然可以,用未公布的34H调用,若21H运行,则返回的ES:BX地址中的值为1,否则为0。
不过记得有些模糊,请参看《软盘加密与解密新技术》一书,台湾人范修维写的,讲的可算是详细备至,深入浅出,比现在的电脑书强多了。
DOS
程序
员手册(十一)
560页 版本5
中
新增加的子功能05h支持
程序
截获MS-
DOS
EXEC
调用
,并实 现自我装载。该子功能能实现内存的修补,如设置装载
程序
能接收的版本号 (通过SETVER设置的版本号)以及实现对装载
程序
在装载时的修补。 在把控制权传送给装载
程序
之前,功能05h应是系统发出的最后一个调 用。尤其是,在该功能成功地返回和把控制传送给装载...
DOS
下多任务系统的设计与实现 (1995-7)
DOS
下多任务系统的设计与实现 (1995-7)作者:wxzself一、引言: 将
DOS
扩展为多任务系统,在理论和实践
中
都有很重要的意义。但由于
DOS
系统单用户,单任务的设计局限,在实现
中
有不少难点。 本文提出一种实现方法及其具体设计。 现有的多任务
DOS
系统,可以分为两类。 一类是在其它多任务系统(如OS/2、UNIX、WINDOWS NT等)的支持下的
DOS
多任务。在这类系统
中
,有着严格
本世纪最经典好文---新系统下经典老游戏[
中
文HGAME]重玩全攻略(感谢作者)
送给所有爱玩游戏的老鸟们 老游戏
中
有大量经典作品,其
中
中
文的HGAME更是经典
中
的经典! ◆ 告别的年代 失色的回忆?——新系统下经典老游戏重玩全攻略 ◆ “新”与“老”当然是相对的,不过在开篇之前有必要确定我们的讨论范畴,这里的“老”是指为Win98之前的操作系统,包括
DOS
和Win32/95,而新系统则是指Win98/2000/XP。毫无疑问,有很多老游戏都很值得我们来重温,但重
DOS
初级教程
DOS
初级教程 2011年09月04日
DOS
(Disk Operating System),是一个磁盘操作系统。它在PC电脑的发展过程
中
占有非常重要的作用,曾几乎一统天下,在世界上有众多的使用者与爱好者。
DOS
有很多版本也有很多种,其
中
最常用的是MS-
DOS
。 一、内部命令 1、DIR 含义:显示指定路径上所有文件或目录的信息 ...
DOS
<61条圣经>完整版
1.
DOS
特点 在
DOS
环境下,开机后,我们面对的不是桌面和图标,而是这样的电脑屏幕:这个C:\>叫做提示符,这个闪动的横线叫做光标。这样就表示电脑已经准备好,在等待我们给它下命令了。我们现在所需要做的,就是对电脑发出命令,给电脑什么命令,电脑就会做什么。那我们又怎么向电脑发布命令呢? 很简单。比如,我们想看看现在几点钟了,就可以输入时间命 令,敲入time四个字母,它在英文
中
汇编语言
21,459
社区成员
41,601
社区内容
发帖
与我相关
我的任务
汇编语言
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
复制链接
扫一扫
分享
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章