|
主题 : : 关于外中断中缓冲区的疑惑? [待解决] |
回复[ 4次 ]
点击[ 715次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2007-06-25 19:08 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-06-23 21:45 |
第269页,用下面的代码替换了系统的int9 中断
int9: push ax
push bx
push es
in al, 60h
pushf
pushf
pop bx
and bh, 11111100b
push bx
popf
call dword ptr ds:[0]
cmp al, 1
jne int9ret
mov ax, 0b800h
mov es, ax
inc byte ptr es:[160*12+40*2+1]
int9ret:pop es
pop bx
pop ax
iret
首先程序可用
问题是这样的,我发现如果在程序运行时候,一直按esc,程序就会报错
昨天我分析了一下,可能是键盘缓冲区是16个字符经过测试,发现的确是这个问题
所以,我想怎么样才能读完按键之后清除键盘缓存区,并且如果用户输入超过了键盘缓存区,我程序怎么处理. | | |
|
|
|
|
[第1楼]
[ 回复时间:2007-10-09 14:41 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:3
注册日期:2007-10-08 15:17 |
你的疑惑我也有
程序调用原来的int 9,
把扫描到的信号存入缓冲区
原来的int 9是个完整的中断,他会处理这个缓冲区吗 | | |
|
|
|
|
[第2楼]
[ 回复时间:2007-10-09 21:41 ]
[引用]
[回复]
[ top ] | |
荣誉值:179
信誉值:6
注册日期:2007-07-09 19:18 |
p269的程序一直按esc不会出错呀?楼主怎么按的?
等开始显示字符后再一直按还会报错吗?
原来的int9中断会处理按键将扫描码和对应的ASCII码送入键盘缓冲区. | | |
|
|
|
|
[第3楼]
[ 回复时间:2007-11-01 12:19 ]
[引用]
[回复]
[ top ] | |
荣誉值:43
信誉值:3
注册日期:2007-07-05 19:53 |
昨天我分析了一下,可能是键盘缓冲区是16个字符经过测试,发现的确是这个问题
---------------------------------------------------------------------
键盘缓冲区是一个环形队列,其性质与《数据结构》课程中对“环形队列”所描述的性质完全一致。虽然键盘缓冲区的本身长度为16个字,即32byte,自地址0040:001E开始。,但出于判断“对列满”的考虑,它最多只能保存15个键盘信息。当缓冲区满时,系统将不再接受按键信息,而会发出“嘟”的声音,以示要暂缓按键。 | | |
|
|
|
|
[第4楼]
[ 回复时间:2007-11-02 13:49 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-10-22 14:47 |
书上这个程序,除了监测点15.1上面的问题之外,还有一个问题就是,主程序在退出的时候,没有恢复原有的9号中断程序,这样当主程序退出之后,你再按键盘,这时候系统自动调用9号中断,而这个时候的中断地址是不正确的,所有,在主程序的mov ax,4c00h之前,还应该恢复原有的9号中断
修改后的程序如下:
assume cs:code
stack segment
db 128 dup(0)
stack ends
data segment
dw 0, 0
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
; 保存原来9号中断的入口地址, data:[0] = int 9 ip, data:[2] = int 9 cs
push es:[9*4] ; int 9 ip
pop ds:[0]
push es:[9*4+2] ; int 9 cs
pop ds:[2]
; 将原来9号中断的地址改为我们写的9号中断地址
cli ; 禁止可屏蔽中断,如果在改写9号中断地址的过程中有按键,则产生9号中断
; 而这个时候由于地址没有改完,则地址是错误的
mov word ptr es:[9*4], offset int9
mov es:[9*4+2], cs
sti ; 恢复中断
mov ax, 0b800h
mov es, ax
mov ah, 'a'
s:
mov es:[160*12+40*2], ah
call delay
inc ah
cmp ah, 'z'
jna s
; 主程序执行完毕,在返回之前,恢复9号中断的地址
cli
mov ax, 0
mov es, ax
mov ax, ds:[0]
mov es:[9*4], ax
mov ax, ds:[2]
mov es:[9*4+2], ax
sti
mov ax, 4c00h
int 21h
delay:
push ax
push dx
mov dx, 2000h
mov ax, 0
s1: sub ax, 1
sbb dx, 0
cmp ax, 0
jne s1
cmp dx, 0
jne s1
pop dx
pop ax
ret
int9:
push ax
push bx
push es
in al, 60h
pushf
call dword ptr ds:[0]
cmp al, 1
jne int9ret
mov ax, 0b800h
mov es, ax
inc byte ptr es:[160*12+40*2+1]
int9ret:
pop es
pop bx
pop ax
iret
code ends
end start | | |
|