例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 | |||