汇编程序:按键松开时中断的处理

来源:互联网 发布:燕郊淘宝店招聘 编辑:程序博客网 时间:2024/06/01 23:21

  当键盘上有键按下时,会产生该键的扫描码,并被送入端口地址为60h的寄存器中。然后,CPU会接受到9h号中断,如果该键是字符码,会将扫描码连同字符码(ASCII码)一起放入缓冲区,而如果该键是控制键和切换键,则会改变内存中对应键盘状态的字节中。
  当要为某按键设置特别的功能时,可以改写int 9h的中断处理程序,也可以调用int 16h BIOS中断,各种方案,这是学习底层的同学要练的基本功。
  问题来了。键盘上按下的键被松开呢?
  当键被松开时,也会产生中断,这时,送入60h端口的,不叫“扫描码”,而叫“断码”。断码=扫描码+80h,即1字节的扫描码最高位均为0,将最高位换1,就是对应键的断码。
  区别仅此而已!
  处理按键松开的技术方案,也就好说了。
  参考博文《汇编程序:显示时间中响应键盘中断》,其功能是:“在屏幕的左上角动态显示时间,期间,按下Home键后,能显示’Home’,按下End键后,退出程序。”
  下面的程序,扩展功能为“在屏幕的左上角动态显示时间,期间,按下Home键后,能显示’Press Home’,松开时,显示’Unpress Home’,按下End键后,退出程序。”。
  请阅读程序,可以运行查看结果来品味。重点看按下Home的扫描码为47h,而松开Home键,得到的断码是0C7h。

assume cs:codestack segment     db 128 dup (0)stack endsdata segment     dw 0,0home db 'Press Home',0dh,0ah,'$'un_home db 'Unpress Home',0dh,0ah,'$'data endscode segmentstart:      mov ax,stack      mov ss,ax      mov sp,128      mov ax,data      mov ds,ax      ; 改中断例程入口地址      mov ax,0      mov es,ax      push es:[9*4]      pop ds:[0]      push es:[9*4+2]      pop ds:[2]      mov word ptr es:[9*4],offset int9      mov es:[9*4+2],cs      ; 显示时间show: mov al,2  ;分      out 70h,al      in al,71h      mov ah,al      mov cl,4      shr ah,cl      and al,00001111b      add ah,30h      add al,30h      mov bx,0b800h      mov es,bx      mov byte ptr es:[0],ah      mov byte ptr es:[1],01001111b      mov byte ptr es:[2],al      mov byte ptr es:[3],01001111b      mov byte ptr es:[4],':'      mov byte ptr es:[5],01001111b      mov al,0    ;秒      out 70h,al      in al,71h      mov ah,al      mov cl,4      shr ah,cl      and al,00001111b      add ah,30h      add al,30h      mov bx,0b800h      mov es,bx      mov byte ptr es:[6],ah      mov byte ptr es:[7],01001111b      mov byte ptr es:[8],al      mov byte ptr es:[9],01001111b      jmp show    ; 定义中断例程int9:      push ax      push bx      push dx      push es      in al,60h      pushf      pushf      pop bx      and bh,11111100b      push bx      popf      call dword ptr ds:[0]      mov bl, al ;保存alpress_home:      cmp al,47h ; 47h是HOME键的扫描码      jne release_home      ;处理HOME      lea dx, home      mov ah,9      int 21h      jmp int9retrelease_home:      cmp al,0C7h ; 0C7h是HOME键的断码      jne press_end      ;处理HOME      lea dx, un_home      mov ah,9      int 21h      jmp int9ret press_end:      cmp bl, 4Fh ;4Fh是end键的扫描码      jne int9ret      ;处理END,使程序结束,注意在此要恢复中断向量      mov ax,0      mov es,ax      push ds:[0]      pop es:[9*4]      push ds:[2]      pop es:[9*4+2]      mov ax,4c00h      int 21hint9ret:pop es      pop dx      pop bx      pop ax      iretcode endsend start