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

简介:   当键盘上有键按下时,会产生该键的扫描码,并被送入端口地址为60h的寄存器中。然后,CPU会接受到9h号中断,如果该键是字符码,会将扫描码连同字符码(ASCII码)一起放入缓冲区,而如果该键是控制键和切换键,则会改变内存中对应键盘状态的字节中。

  当键盘上有键按下时,会产生该键的扫描码,并被送入端口地址为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:code

stack segment
     db 128 dup (0)
stack ends

data segment
     dw 0,0
home db 'Press Home',0dh,0ah,'$'
un_home db 'Unpress Home',0dh,0ah,'$'
data ends

code segment
start:
      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 ;保存al
press_home:
      cmp al,47h ; 47h是HOME键的扫描码
      jne release_home
      ;处理HOME
      lea dx, home
      mov ah,9
      int 21h
      jmp int9ret

release_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 21h

int9ret:pop es
      pop dx
      pop bx
      pop ax
      iret

code ends
end start
目录
相关文章
加快软盘操作速度的汇编程序源代码
加快软盘操作速度的汇编程序源代码
|
4月前
51单片机用汇编语言实现独立按键检测,每个按键有不同功能,包含按键消抖程序
51单片机用汇编语言实现独立按键检测,每个按键有不同功能,包含按键消抖程序
140 3
|
4月前
|
程序员 编译器 数据处理
汇编高手秘籍:解锁性能优化新境界,用汇编语言让你的程序飞起来!
【8月更文挑战第31天】汇编语言作为编程基石,其高效性能备受推崇。尽管现代软件开发更偏爱高级语言,但在性能要求极高的场景下,汇编优化仍不可或缺。本文通过示例代码介绍四种优化技巧:循环展开、寄存器分配、指令重排及SIMD指令使用,显著提升执行效率。同时强调分析性能瓶颈、测试优化效果及保持代码可读性的重要性,助力开发者在关键代码路径上实现性能突破。
116 0
8086 汇编笔记(五):包含多个段的程序
8086 汇编笔记(五):包含多个段的程序
|
7月前
|
编译器 开发者 C++
8086 汇编笔记(三):第一个程序
8086 汇编笔记(三):第一个程序
|
6月前
|
C语言
程序技术好文:部分ARM汇编指令解读
程序技术好文:部分ARM汇编指令解读
|
7月前
|
存储 编译器
C51汇编程序
C51汇编程序
71 5
|
存储 Java C++
汇编语言、寄存器分类及程序计数器
汇编语言、寄存器分类及程序计数器
151 0
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(三)
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(三)
|
编译器 C语言
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(二)
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(二)