例10.15 在NumLock处于“开状态”时,每按小键盘(Numeric Keypad)上的数字键,给出“啪啪”响声。
解: | ||||
CSEG | SEGMENT 'CODE' | |||
ORG 100H | ||||
start: | ||||
JMP | init | |||
INT9 | DD ? | |||
TSR: | ||||
PUSH | AX | |||
PUSH | CX | |||
PUSH | DS | ;保存寄存器 | ||
MOV | AH, 2 | |||
INT | 16H | ;读取键盘当前状态 | ||
TEST | AL, 00100000B | ;检测NumLock的状态 | ||
JZ | TSRExit | |||
IN | AL, 60H | |||
CMP | AL, 71 | |||
JL | TSRExit | |||
CMP | AL, 83 | |||
JG | TSRExit | |||
MOV | AL, 10110110B | |||
OUT | 43H, AL | ;向端口43H送特定的数0B6H | ||
MOV | AX, 1000 | |||
OUT | 42H, AL | |||
MOV | AL, AH | |||
OUT | 42H, AL | ;向端口42H送声音频率 | ||
IN | AL, 61H | ;读取扬声器的当前状态 | ||
MOV | AH, AL | ;把扬声器的状态保存在AH中 | ||
OR | AL, 03 | |||
OUT | 61H, AL | ;开声音 | ||
MOV | CX, 9000 | |||
delay: | ||||
LOOP | delay | ;声音延迟 | ||
MOV | AL, AH | |||
OUT | 61H, AL | ;恢复扬声器原来的状态,即关声音 | ||
TSRExit: | ||||
POP | DS | |||
POP | CX | |||
POP | AX | ;恢复寄存器 | ||
JMP | CS:INT9 | ;转向中断9H原来的处理程序 | ||
init: | ||||
CLI | ;关中断 | |||
MOV | AH, 35H | |||
MOV | AL, 09H | |||
INT | 21H | |||
MOV | WORD PTR INT9, BX | |||
MOV | WORD PTR INT9+2, ES | ;保存中断9H原处理程序入口地址 | ||
MOV | AH, 25H | |||
MOV | AL, 09H | |||
LEA | DX, TSR | |||
INT | 21H | ;设置中断9H新的处理程序入口地址 | ||
STI | ;开中断 | |||
LEA | DX, init | |||
ADD | DX, 15 | |||
MOV | CL, 4 | ;把init的偏移量转换成“节数” | ||
SHR | DX, CL | ;每节内有16个字节 | ||
MOV | AX, 3100H | |||
INT | 21H | |||
CSEG | ENDS | |||
END | start |