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