| 功能号 | 入口参数 | 出口参数 |
| 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 ?