. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->外中断
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  模拟键盘输入  [待解决] 回复[ 9次 ]   点击[ 728次 ]  
cnhnyu
[帖 主]   [ 发表时间:2007-11-16 11:24 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2007-10-22 14:47
我们都知道,当一个按键按下去之后,计算机做如下的动作:
1)键盘产生扫描码
2)扫描码送入60H端口
3)引发9号中断
4) CPU执行9号中断例程处理键盘输入

键盘缓冲区起始地址位于0040:001a处,长度为36字节,其中前4字节用于保存键盘缓冲区的首指针和尾指针,后面的32个字节,是真正存放键盘扫描码的地方。即
0040:001a 键盘缓冲区首指针 2个字节
0040:001c 键盘缓冲区尾指针 2个字节
0040:001e 键盘扫描码和ascii码存放的开始位置, 共16个字,可以存放15个键盘输入
这是一个环形队列,为了准确判断缓冲区是满还是空,特地保留了一个字。
一个键盘输入占用2个字节,低字节存放ASCII码,高字节存放扫描码。
下面的小程序,模拟键盘,输入DEBUG,回车,r,回车,Q,回车
产生的效果是,当程序运行後,自动输入一个debug,调出debug,然后用r显示寄存器内容,接着输入debug的q命令退出debug

代码如下:
code segment
        assume cs:code
main proc far
        mov ax, 0040h     ;键盘缓冲区段地址
        mov ds, ax        ; 送入ds
        mov word ptr ds:[001ah], 001eh    ; 键盘缓冲区首指针指向扫描码和ASCII码存放的首地址
        mov bx, 001eh                     ; bx指键盘输入缓冲区首地址
        mov word ptr ds:[bx], 2044h        ; D 将字母'D'的扫描码和ASCII码放入键盘输入缓冲区首地址
        mov word ptr ds:[bx+2], 1245h        ; E  接着放入字母'E'的扫描码和ASCII码
        mov word ptr ds:[bx+4], 3042h        ; B  
        mov word ptr ds:[bx+6], 1655h        ; U
        mov word ptr ds:[bx+8], 2247h        ; G
        mov word ptr ds:[bx+10], 1c0dh        ; return 送入一个回车,执行命令
        mov word ptr ds:[bx+12], 1372h        ; r   送入字母'r',显示寄存器内容
        mov word ptr ds:[bx+14], 1c0dh        ; return 送入回车,执行'r'命令
        mov word ptr ds:[bx+16], 1051h        ; q      送入'q'
        mov word ptr ds:[bx+18], 1c0dh        ; return 执行'q'命令,退出debug
        add bx, 20
        mov ds:[001ch], bx              ; 调整键盘缓冲区尾指针,指向最后一个键盘输入

        mov ax, 4c00h
        int 21h        
main endp

code ends
        end main

一块交流,共同进步【http://www.anijh.cn】
Wednesday
[第1楼]   [ 回复时间:2007-12-21 14:38 ]   [引用]   [回复]   [ top ] 
荣誉值:43
信誉值:3
注册日期:2007-07-05 19:53
倒是挺有意思。
fishboy
[第2楼]   [ 回复时间:2007-12-23 10:53 ]   [引用]   [回复]   [ top ] 
荣誉值:283
信誉值:0
注册日期:2007-06-26 11:42
楼主的思维方式挺让人眼前一亮。能搞!!
yw007
[第3楼]   [ 回复时间:2008-01-23 09:16 ]   [引用]   [回复]   [ top ] 
荣誉值:5
信誉值:0
注册日期:2007-12-16 10:57
能解释一下main proc far 、main endp和end main语句吗?谢谢
abcabc
[第4楼]   [ 回复时间:2008-01-23 09:39 ]   [引用]   [回复]   [ top ] 
荣誉值:24
信誉值:3
注册日期:2007-06-06 11:53
给楼上的兄弟改改,其实没用~


王爽老师的汇编语言版;)

代码如下:
assume cs:code  
code segment  
start:
    mov ax, 0040h     ;键盘缓冲区段地址 
    mov ds, ax        ; 送入ds 
    mov word ptr ds:[001ah], 001eh    ; 键盘缓冲区首指针指向扫描码和ASCII码存放的首地址 
    mov bx, 001eh                     ; bx指键盘输入缓冲区首地址 
    mov word ptr ds:[bx], 2044h    ; D 将字母'D'的扫描码和ASCII码放入键盘输入缓冲区首地址 
    mov word ptr ds:[bx+2], 1245h    ; E  接着放入字母'E'的扫描码和ASCII码 
    mov word ptr ds:[bx+4], 3042h    ; B   
    mov word ptr ds:[bx+6], 1655h    ; U 
    mov word ptr ds:[bx+8], 2247h    ; G 
    mov word ptr ds:[bx+10], 1c0dh    ; return 送入一个回车,执行命令 
    mov word ptr ds:[bx+12], 1372h    ; r   送入字母'r',显示寄存器内容 
    mov word ptr ds:[bx+14], 1c0dh    ; return 送入回车,执行'r'命令 
    mov word ptr ds:[bx+16], 1051h    ; q      送入'q' 
    mov word ptr ds:[bx+18], 1c0dh    ; return 执行'q'命令,退出debug 
    add bx, 20 
    mov ds:[001ch], bx              ; 调整键盘缓冲区尾指针,指向最后一个键盘输入 

    mov ax, 4c00h 
    int 21h     

code ends 
end start 


这样看着就舒服了吧~
yw007
[第5楼]   [ 回复时间:2008-01-24 11:02 ]   [引用]   [回复]   [ top ] 
荣誉值:5
信誉值:0
注册日期:2007-12-16 10:57
清楚了,谢谢。感觉自己知道的还是太少。
yw007
[第6楼]   [ 回复时间:2008-01-25 08:38 ]   [引用]   [回复]   [ top ] 
荣誉值:5
信誉值:0
注册日期:2007-12-16 10:57
我在电脑上输入试了一下,以上程序很不稳定,有时能够执行,有时能执行一部分。
jackliu
[第7楼]   [ 回复时间:2008-09-15 11:37 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:1
注册日期:2008-09-05 11:19
原来可以这样做的,,学习了,,不过觉得代码还是可以简化的,在用BX相对寻址时默认的数据段为DS,所以在用BX相对寻址时可以不用段超越前缀,,
k5feen
[第8楼]   [ 回复时间:2008-10-21 09:32 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-09-17 18:28
楼主的最后的代码应该是add  bx,20h吧
811179242
[第9楼]   [ 回复时间:2008-11-20 20:40 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-11-20 20:14
有意思 终于知道键盘缓冲区干啥的了 呵呵
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved