;MASM编译通过。
;==========================================================================
;安装一个新的 INT 9 中断例程,功能:在 DOS 下,按下"A"后,除非不再松开,
;如果松开,就显示满屏幕的"A",其他的键照常处理.
;提示:断码=通码+80H
;==========================================================================
ASSUME CS:CODE
STACK SEGMENT
DB 128 DUP (0)
STACK ENDS
CODE SEGMENT
START:
MOV AX,STACK ;初始化DS
MOV SS,AX
;把原9号中断的IP、CS暂存到0:200H和0:202H处
MOV AX,0
MOV ES,AX
PUSH ES:[9*4]
POP ES:[200H]
PUSH ES:[9*4+2]
POP ES:[202H]
;(DS)=(CS)
PUSH CS
POP DS
;复制新的 INT 9 中断到0:204H处
MOV SI,OFFSET INT9START
MOV DI,204H
MOV CX,OFFSET INT9END-OFFSET INT9START
CLD
REP MOVSB
;设置新的 INT 9 中断的入口地址
CLI ;设置新的 INT 9 中断的入口地址,置(IF)=0,不响应可屏蔽中断,
;以免指向错误的地址
MOV WORD PTR ES:[9*4],204H ;(IP)=204H
MOV WORD PTR ES:[9*4+2],0 ;(CS)=0
STI ;恢复响应可屏蔽中断
;测试新的 INT 9 中断
MOV AX,0B800H
MOV ES,AX
MOV AH,'A'
MOV BX,12*160+40*2
S:
MOV ES:[BX],AH
CALL DELAY
INC AH
INC BX
INC BX
CMP AH,'Z'
JNA S
MOV AX,4C00H
INT 21H
;新的 INT 9 中断
INT9 PROC NEAR
INT9START:
PUSH AX ;保护现场
PUSH CX
PUSH DI
PUSH ES
IN AL,60H ;从端口获取输入
;调用原 INT 9 中断
PUSHF
CALL DWORD PTR CS:[200H]
CMP AL,9EH ;9EH = A的断码
JNE INT9RET ;松开A,跳转到INT9RET
;输出满屏幕的A
MOV AX,0B800H
MOV ES,AX
MOV DI,0
MOV CX,2000
INT9S:
MOV BYTE PTR ES:[DI],'A'
INC DI
INC DI
LOOP INT9S
INT9RET:
POP ES ;恢复现场
POP DI
POP CX
POP AX
IRET ;返回
INT9END:
NOP
INT9 ENDP
;延时子程序
DELAY PROC NEAR
PUSH AX
PUSH DX
MOV DX,10H
MOV AX,0
S1:
SUB AX,1
SBB DX,0
CMP AX,0
JNE S1
CMP DX,0
JNE S1
POP DX
POP AX
RET
DELAY ENDP
CODE ENDS
END START