. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->使用BIOS进行键盘输入和磁盘读写
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  关于键盘缓冲区的问题  [待解决] 回复[ 13次 ]   点击[ 1521次 ]  
dontbend
[帖 主]   [ 发表时间:2007-11-02 20:07 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:13
注册日期:2007-09-26 02:27
请问在debug下,是不是按下一个键,键盘缓冲区就会存入
一个键的扫描码和ascii码? 那么比方17.2中的例题,为什么在执行int 16h之前键盘缓冲区一定是空的?为什么int 16h就一定是在等待用户去新按下的键呢(如r,g)?
cat442
[第1楼]   [ 回复时间:2007-11-03 10:08 ]   [引用]   [回复]   [ top ] 
荣誉值:16
信誉值:6
注册日期:2007-06-26 16:56
请问在debug下,是不是按下一个键,键盘缓冲区就会存入
一个键的扫描码和ascii码

bios 16h 中断可以读取键盘缓冲,这是bios提过的功能。至于debug下的具体情况是怎样你不用这么关心,只要如实反应你的程序执行过程就好,debug不就是个调试工具吗?你的程序最终是让cpu连续的执行的,debug只是一个反应一个检验的环境而已,不要受debug的影响。

至于你的后两个问题,建议你把17.2小节在仔细读读,看看有没有新的认识。
dontbend
[第2楼]   [ 回复时间:2007-11-03 19:44 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:13
注册日期:2007-09-26 02:27
谢谢cat442的回吧,
我已经把17章都读过了,我上面提到的问题,我还是搞不清楚,bios在什么环境下回调用int9中断把键信息写入键盘缓冲区? 以及上面我提到的后两个问题?
dontbend
[第3楼]   [ 回复时间:2007-11-04 21:12 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:13
注册日期:2007-09-26 02:27
现在我的为问题就是为什么我们的程序执行前键盘缓冲区一定是空的?
cat442
[第4楼]   [ 回复时间:2007-11-05 18:38 ]   [引用]   [回复]   [ top ] 
荣誉值:16
信誉值:6
注册日期:2007-06-26 16:56
你这个问题有误导的嫌疑,难道在你执行int 16h 之前键盘缓冲区就一定是空的吗?如果是那只有一种可能,就是键盘中断自己直接或间接把按键码清除掉,不过这样它键盘中断也没意义了。

我记得书上只是说 int 16h 只是每次读取键盘缓冲区键盘缓冲区 在非空的情况下取走其中第一个单元的一个字节,按键的扫描码和ascll码。还有键盘缓冲区的结构是一个环形队列。于是我推测这第一个就是这个队列的头。

现在我不确定它空还是非空,呵呵,晕了,不过我知道它空不空,因为我不知道在程序加载前有没有谁,进行了清除键盘缓冲区的操作。但是我想它空不空,应该不影响你继续学习吧。
我去学习学习,学艺不精啊 !
dontbend
[第5楼]   [ 回复时间:2007-11-05 20:05 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:13
注册日期:2007-09-26 02:27
我没有误导的意思,因为我自己还没有明白,我怎么会误导别人呢?我只是按程序运行的结果来推测。

问题是我们运行程序之前键盘缓冲区不为空,为什么没有取出这些非空键盘缓冲区中已有键的信息呢?
这个问题有人能专业一点的回答吗?
cat442
[第6楼]   [ 回复时间:2007-11-05 23:40 ]   [引用]   [回复]   [ top ] 
荣誉值:16
信誉值:6
注册日期:2007-06-26 16:56
我简单说说键盘中断,键盘中断是怎么发生的呢? 在TF被设置成1时,才可以,因为键盘中断是外中断,一说可屏蔽中断。
键盘有按键的时候,键盘的控制电路会工作,向cpu报告中断传递中断码,,是通过控制线也就是和cpu相连的中断引脚,键盘控制电路还要找出按键,通过扫描算法得到按键,把键码送到相应端口; cpu 接到中断信号,如果允许则读出中断码,定位中断向量,执行中断程序。由中断程序(int 9)读出按键码,放入缓冲区;如果不允许中断(IF=0)则不理会这个中断信息。

至于16h可以有两种方式读取按键,一种是读键盘输入,也就是书中提到的那样,把缓冲区第一个单元读出并删除。
还有一种是读缓存中的按键,如果读到按键它不进行删除(if a keystroke is present, it is not removed from the keyboard buffer)避免我译错把英文贴上来吧。此外,如果读不到将ZF置一。

第一种:
mov ah,0 
int 16h
第二种:
mov ah,1
int 16h

是不是空大概一试就知道了。

之前像是我在误导你了,不好意思。我认为程序执行前键盘缓冲区为空与否不能确定,但是我没有直接找到证据。看来为空更合逻辑一点。我按照这面的方式试了一下zf=1.
键盘中断发生后势必引发相应的处理,除非键盘可以自己把按键送到缓冲区,或者发生键盘中断后没有人来读按键,显然这两种情况都不怎么合乎逻辑。
dontbend
[第7楼]   [ 回复时间:2007-11-06 19:56 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:13
注册日期:2007-09-26 02:27
感谢cat442耐心的回复本题。
如果有人还有不同的看法,请继续帖出来!
cxn
[第8楼]   [ 回复时间:2007-11-14 14:42 ]   [引用]   [回复]   [ top ] 
荣誉值:179
信誉值:6
注册日期:2007-07-09 19:18
cat442 在6楼说的很对.
我对帖主提出的问题来一个直接的回答.说明为什么在debug下键盘缓冲区看到的都是空的.
首先想想debug的工作过程
将程序加载到内存,等待用户输入,假如此时有按键会被debug接收显示出来并且清空键盘缓冲区.
调试程序时跟上面情况类似,也就是说按键都被debug接收了,所以在调用16H中断时会始终等待用户输入.

可以编一个这样的程序

call delay ;延时5秒     在延时过程中按键都会存储到键盘缓冲区
mov ah,0
int 16H ;读取键盘缓冲区
over : 
用g命令执行到over处
在延时的过程中按键 比如输入"abcdef"  5s时间足够了 呵呵.
此时16h号中断就没有等待用户输入而是将'a'读入了ah,然后退回的debug 此时debug接收到了剩下的字母"bcdef".也就是说如果在debug时键盘缓冲区不是空的,那么键盘缓冲区的内容就会被debug接收了.所以轮到程序执行时键盘缓冲区必然是空的.
不知帖主明白了没有,可以试验一下体会一下.
dontbend
[第9楼]   [ 回复时间:2007-11-15 19:54 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:13
注册日期:2007-09-26 02:27
上面的那个测试很有意义,又进一步明白了很多。谢谢cxn帮助!
cxn
[第10楼]   [ 回复时间:2007-11-21 17:35 ]   [引用]   [回复]   [ top ] 
荣誉值:179
信誉值:6
注册日期:2007-07-09 19:18
不客气,呵呵.慢慢体会键盘缓冲区的原理.
zhujinwu
[第11楼]   [ 回复时间:2011-12-02 23:08 ]   [引用]   [回复]   [ top ] 
荣誉值:15
信誉值:0
注册日期:2011-11-03 09:29
这样一说,倒是明白了很多。谢谢。
1152659530
[第12楼]   [ 回复时间:2023-08-15 18:51 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2023-07-25 10:13
谢谢解答,我才能明白。
1152659530
[第13楼]   [ 回复时间:2023-08-15 18:54 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2023-07-25 10:13
好像280页也是用的这种方法,
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved