怎样得到INT13H 的busy标志及INT21H(AH=34H):MS-DOS工作标志

xjslj 2000-03-28 01:54:00
我做了一个TSR程序,需要在存盘前先侦测当前有无存盘动作正在进行.一是看INT13H 的busy标志,二是看Indos标志(MSDOS工作标志),但是, 我不知怎样得到这些标志,及这些标志的内容、含义? 查了许多资料没查着,好象是尚未公开的DOS内核。
...全文
281 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
kacer 2001-01-14
  • 打赏
  • 举报
回复
如果问题解决了,请给分。
不要部将问题留在“未解决”区。
bigluo 2000-06-26
  • 打赏
  • 举报
回复
int 13h 要自己设置,就象上一篇所说明的一样,int 21h 的如下,这篇文章发布在我自己的主页 http://asm.yeah.net 中,如果需要其他资料,可以去那儿找!文章如下:
=========================================================================
大家都知道,DOS 是一个单用户的操作系统,它的核心程序是不允许重入的,说的具体一点,如果我们要编一个递归调用的程序,我们会把参数放在堆栈里,而不是用设置变量的方法,这样在下一层程序返回时,不会有临时变量被改变的危险,而 DOS 在处理中断 INT 21H 时使用的临时数据是放在内部数据区内的,如果在一个 INT 21H 过程中再发生另一个 INT 21H,在第二个 INT 21H 执行完以后回到第一个 INT 21H 时,原来保存的临时数据就不是原来的样子了,而是第二个 INT 21H 执行完后留下的‘垃圾’,编一个内存驻留程序,随时弹出一个窗口执行 INT 21H 功能,要想不死机,就必须先解决 DOS 的重入问题。
解决重入问题有两种方法,第一种是在进入 INT 21H 前人为保存 DOS 的内部数据结构到自己的缓冲区,在执行完后恢复,这种方法依赖于 DOS 的内部资料,而且不同的 DOS 版本的数据结构、数据位置是不一样的,使用起来有相当的难度,而且对新版的操作系统的兼容程度是未知的。
常用的办法是在要激活驻留程序前,先检测 DOS 的状态,如果 DOS 是空闲的,就可以马上激活,如果DOS 忙,就等到 DOS 空闲后再激活。本文就是讨论检测 DOS 状态的方法。
实际上,DOS 本身已经或多或少的考虑了这个问题,它本身有个 InDOS 标志,在执行 DOS 功能时,它会把标志 +1,退出时 -1,如果检测 InDOS 不是 0,就说明 DOS 的某些功能在执行中。DOS 功能 INT 21H的 34H 子功能即是得到 InDOS 标志的地址,在这个标志前一个字节是 DOS紧急错误标志。在 DOS 忙判断上有两个特殊情况,一是 DOS 在紧急错误时会减少 InDOS 标志,所以检测到 InDOS 为 0 时还要确定错误标志为 0,进入 DOS 才是安全的,二是有些 DOS 功能本身就允许重入,它们是一些不用到内部数据区的输入命令等,如等待命令输入时 DOS 执行的是输入子功能,这时的 InDOS 为 1,但实际上是允许进入 DOS 的,在这中情况下,DOS 会不停的发 INT 28H 中断,原来的 INT 28H 功能是不做任何事马上返回。用户可以在 INT 28H中挂上自己的程序而不必担心 DOS 重入。
具体的编程示例见源程序,方法是截取 INT 28H 和 INT 21H,在检测到热键后,一般设置一个标志,然后在新的 INT 28H 和 INT 21H 中检测 DOS 是否空闲再进入。

  本程序要用到的 INT 21H 的 34H 功能如下:

功能号 入口参数 出口参数
AH = 34H
得到 InDOS 标志的地址 无 ES:BX 指向 InDOS 标志,前一个字节为 DOS 紧急错误标志

源程序:

;Copyright by LuoYunBin
;http://asm.yeah.net


...
; 数据定义

DOS_ERROR DB 0 ;dos error flag
IN_DOS_TIMES DB 0 ;InDos flag
Off_InDos DW ? ;保存InDos 标志地址
Seg_InDos DW ?

;我们在热键中检测到要激活时,把 Flag 的位 0 置 1,然后再在 Int 28h 和 Int21h
;中判断 DOS 空闲在进入
Flag db 0

...

mov ah,34h ;取 InDos 标志地址
int 21h
mov off_InDos,bx
mov seg_InDos,es
...

;==========get dos error & busy flag===================
;取 DOS 标志和紧急错误标志的子程序

IN_DOS PROC
pushf
push si
push ds
push ax
lds si,dword ptr cs:off_InDos
dec si
lodsb
mov cs:dos_error,al ;dos in fatel error's flag
lodsb
mov cs:in_dos_times,al ;times of re-enter DOS
pop ax ;normal equ 1 or 0
pop ds ;if > 1, DOS is really busy
pop si
popf
ret
IN_DOS ENDP
;新的 int 28h 中断程序,在这儿判断 DOS 是否忙并执行主程序
;在 DOS 命令行等待输入时的激活将由此进入

int28:
pushf
call in_dos ;由于 int 28h 由 DOS内部发出
cmp cs:in_dos_times,1 ;所以 InDos > 1,DOS 才是忙的
ja int28_quit
cmp cs:dos_error,0 ;如果在 DOS 错误中,就无法激活
jnz int28_quit
test cs:flag,00000001b ;是否检测到过热键
jz int28_quit
call main ;激活主程序,不过别忘了在主程序中
int28_quit: ;设置标志防止自己也被重入了!!
popf
db 0eah ;即 JMP seg28:off28 的机器码
OFF28 DW ? ;驻留时把原 int 28h地址保存到这儿
SEG28 DW ?
;新的 int 28h 中断程序,在这儿也要判断 DOS 是否忙并执行主程序
;打断别的程序再激活一般由此进入,如果你觉得激活的途径还不够
;多,那么在检测热键的程序中再加上跟下面同样的代码!

int21:
pushf
push ds

cmp 自己的 main 是否在执行中
jz int21_quit ;first time--quit
test flag,00000001b ;是否检测到过热键
jz int21_quit
call in_dos
cmp in_dos_times,0 ;InDos 标志不等于 0 是危险的
jnz int21_quit ;and not in dos error---active
cmp dos_error,0
jnz int21_quit
call main
int21_quit:
pop ds
popf
DB 0EAH
OFF21 DW ?
SEG21 DW ?
pccrazy 2000-06-16
  • 打赏
  • 举报
回复
INT 13H 的busy标记是要靠你自己设置,例如:

;接管INT 13H
New_Int13:
jmp @label1
is_busy db 0 ;
@label:
mov cs:is_busy,1
pushf
call cs:old_int13 ;调用原来的13号中断
mov cs:is_busy,0
iret
...

只要is_busy = 1 就为忙

kacer 2000-06-16
  • 打赏
  • 举报
回复
INT 13H没有busy标记,但可以在自己的TSR程序中增加这样的标记。
INT 21H的InDOS标记,等我查过之后再告知。
Wonny 2000-06-15
  • 打赏
  • 举报
回复
修改 INT 13H 每调用则设置标志。Indos 好象是 INT 28H 吧。可惜我的书都被人掠走了,我的书上原来是有的。好象〈操作系统原理DOS编〉里面有类似的东西。
sunhongbo 2000-06-14
  • 打赏
  • 举报
回复
关于Indos标志可以参照一本名称大概是未公开的秘密(dos)的书,以前,我在这本书中看过,我再找一下我原来写的程序。
email:yfms@263.net
yfms@hl.cninfo.net
sunhbo@public.hldqptt.net.cn
coolie 2000-05-27
  • 打赏
  • 举报
回复
find a book of dos interrupt
AntiMatter 2000-03-28
  • 打赏
  • 举报
回复
难道没有人能回答这个问题吗

21,453

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧