首页 > 编程语言 >汇编实验:自定义键盘中断的处理函数

汇编实验:自定义键盘中断的处理函数

时间:2022-11-29 15:37:07浏览次数:41  
标签:自定义 中断 ah al mov 键盘 ax 处理函数 21h

汇编实验报告-键盘中断

1. 实验任务:采用键盘中断方式,当输入是字符或数字的时候,回显输入并回车换行;否则退出。

2. 运行环境:Windows11+MASM

3. 题目分析:

在课上我们刚刚学习了中断的概念以及自定义中断,且有一个例程是对键盘中断进行获取的。因此我们可以借鉴例程,通过mov ah 25h/35h完成对键盘中断的存取和设置,获取键入的字符。

但是最开始想直接输出获取的字符却发现均为乱码,查询后才发现由键盘中断方式读取的是字符的扫描码,该码与ASCII码不同,是键盘上第一排“0-9,-=”有邻近的扫描码,第二排“qwertyuiop[]|”有邻近的扫描码等等。于是我们找到扫描码和字符的对应表,手动创建一个字符串,存储从00H-39H的所有字符,如果不是可显示字符,或是控制字符,就用#代替。通过这种方式可以把扫描码直接映射到对应字符的ASCII码输出。

4. 流程图绘制:根据分析和题目要求绘制主函数的流程图:

image-20221102163732393

5. 各部分与功能的流程图/程序:

  1. 数据段定义:当我们定义数据段时,我们要考虑的有以下几方面因素:
  • 由于设置中断前必须保存原有中断处理函数,结束后必须恢复原中断,因此需要2个存储区分别存储原有中断的段地址和偏移地址。

  • 由于需要把扫描码转换为ASCII码输出,我们需要定义一个字符串,其与串首址的偏移距离即为扫描码,其值即为ASCII码。

    数据段定义:

data  segment
old_ip09 dw ?
old_cs09 dw ?
endmsg db 0ah,0dh,'END',0ah,0dh,'$'
scan db "##1234567890-=##qwertyuiop[]##asdfghjkl;'###zxcvbnm,./",'$'
data  ends

codesg segment
  1. 中断处理函数kbdit:
    该函数就是当我们触发键盘中断时,会调用的处理程序。其功能为首先从键盘缓冲区端口60H接受扫描码,然后与数据段中我们定义的字符串偏移量匹配,如果是#则放弃输出,否则判断为正确字符、输出该字符。
  • 流程图
    image-20221103220126967
  • 程序段代码如下:
kbdit PROC

  push dx
  push ax
  push bx
  in      al,60h
  push    ax
  in     al,61h
  mov     ah,al
  or      al,80h
  out     61h,al
  xchg    ah,al
  out     61h,al
  pop     ax
  in      al,60h
  test    al,80h;若超过127,退出
  jnz     return
  lea bx,scan

DISPLAY:
 ;CBW
;     mov cx,ax
; GO:
  sub ah,ah
  ADD bx,ax
  mov     dl,[bx]
  cmp dl,'#';不合格
  je exit
  mov     ah,02H
  int     21h

return:
  cli
  mov     al,20h
  out     20h,al
  pop bx
  pop dx
  pop     ax
  iret
kbdit ENDP
  1. 主函数main

    主函数的作用是设置中断向量,并且进行延时,等待中断程序的调用。

  • 流程图

    image-20221103212731936
  • 程序段代码如下:

main  proc  near
start:
    push    ds
    sub     ax,ax
    push    ax
    mov ax,data
    mov ds,ax
    mov es,ax
    ;save old inter
    mov al,09h
    mov ah,35h;取中断向量
    int 21h
    mov old_cs09,es;保存原有中断
    mov old_ip09,bx
    push    ds
    lea     dx,kbdit
    mov     ax,seg kbdit
    mov     ds,ax
    mov     al,09h
    mov     ah,25h;中断向量设置
    int     21h
    pop     ds
;打开键盘中断屏蔽
    in      al,21h
    and     al,0fdh;00001111
    out     21h,al
    sti
;开始准备服务中断
    mov     di,20000
wait1:
    mov     si,3000
wait2:
    dec     si
    jnz     wait2
    dec     di
    jnz     wait1
    mov     ah,09h
    lea     dx,endmsg
    int     21h
    cli
;恢复原先的中断
    push    ds 
    mov     dx,old_ip09
    mov     ax,old_cs09
    mov     ds,ax
    mov     al,09h
    mov     ah,25h
    INT     21h
    pop     ds  
    ret
;结束
exit:
    lea dx,endmsg
    mov ah,09h
    int 21h
    mov ah,4ch
    int 21h

main ENDP

6.运行结果

  1. 0-9数字排的输出

    image-20221103213913472

  2. 三个字母排的输出

    image-20221103214113321

可见功能正常,成功实现。

  1. 现存问题:由于我们认为SHIFT是不合法的字符,因此我们无法实现SHIFT+小写字母输出大写字母的功能。

标签:自定义,中断,ah,al,mov,键盘,ax,处理函数,21h
From: https://www.cnblogs.com/czy-blogs/p/16935489.html

相关文章

  • android自定义view实现progressbar的效果
    一键清理是很多Launcher都会带有的功能,其效果也比较美观。实现方式也许有很多中,其中常见的是使用图片drawable来完成的,具体可以参考这篇文章:​​模仿......
  • mysql-单行处理函数
    1单行处理函数lower()对于输出转换成小写upper()对于输出转换成大写substr()取子字符串下标从1开始length()去长度concat()将字符串进行拼接......
  • c语言自定义输出小数点位数
    C语言中常用的小数有两种类型,分别是float或double;float称为单精度浮点型,double称为双精度浮点型。不像整数,小数没有那么多幺蛾子,小数的长度是固定的,float始终占用4个......
  • 如何在yum.conf配置文件中指定自定义的yum库文件目录?
    使用自定义的yum库文件,方法非常的简单,只需2个步骤:1、创建自定义yum源目录2、修改yum.conf配置文件 具体的操作如下:1、创建yum源目录 mkdir-p/etc/yum.......
  • 在ionic2中自定义服务:该服务需要使用到NavController
        如果在自定义的服务中的constructor中直接注入(NavControlll)privatenavCtrl:NavController,然后再page页面或组件中的constructor中也采用注入的方式,可能会出现......
  • Android自定义搜索框(EditText)的搜索功能实现,过滤ListView
    实现自定义搜索框(实际上就是一个EditText):<RelativeLayoutandroid:id="@+id/music_search_rl"android:layout_width="match_parent"android:layout_......
  • JSP中的自定义标签
    目录​​目录​​​​简介​​​​入门案例​​​​自定义标签功能扩展​​​​传统自定义标签的运行原理​​​传统自定义标签的使用​​​控制JSP页面部分内容执行​​​......
  • MySQL自定义函数
     ⚠不推荐将业务逻辑存储在数据库中.MySQL不仅提供了很多很方便的内置函数,用户还可以自定义函数。不同于MongoDB对Js函数的良好支持,MySQL的自定义函数用起来感觉处处掣......
  • iOS开发之自定义ActionSheet视图
    有时我们需要用到actionSheet来展示,但是但是往往系统的界面显示很丑或者并不符合UI的要求,所以在这里自定义一个,方便以后使用,后续有时间写一下Swift的开发。自定义ActionShee......
  • JAVA-API概述-Scanner类键盘录入数据
    代码一packagecom.itheima.api;importjava.util.Scanner;publicclassDemo1Scanner{/*next():遇到了空格,就不再录入数据了结......