. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->外中断
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  关于外中断中缓冲区的疑惑?  [待解决] 回复[ 4次 ]   点击[ 715次 ]  
hello
[帖 主]   [ 发表时间: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个字符经过测试,发现的确是这个问题  
  所以,我想怎么样才能读完按键之后清除键盘缓存区,并且如果用户输入超过了键盘缓存区,我程序怎么处理.
yu7856288
[第1楼]   [ 回复时间:2007-10-09 14:41 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:3
注册日期:2007-10-08 15:17
你的疑惑我也有
程序调用原来的int 9,
把扫描到的信号存入缓冲区
原来的int 9是个完整的中断,他会处理这个缓冲区吗
cxn
[第2楼]   [ 回复时间:2007-10-09 21:41 ]   [引用]   [回复]   [ top ] 
荣誉值:179
信誉值:6
注册日期:2007-07-09 19:18
p269的程序一直按esc不会出错呀?楼主怎么按的?

等开始显示字符后再一直按还会报错吗?


原来的int9中断会处理按键将扫描码和对应的ASCII码送入键盘缓冲区.
Wednesday
[第3楼]   [ 回复时间:2007-11-01 12:19 ]   [引用]   [回复]   [ top ] 
荣誉值:43
信誉值:3
注册日期:2007-07-05 19:53
昨天我分析了一下,可能是键盘缓冲区是16个字符经过测试,发现的确是这个问题   
---------------------------------------------------------------------
键盘缓冲区是一个环形队列,其性质与《数据结构》课程中对“环形队列”所描述的性质完全一致。虽然键盘缓冲区的本身长度为16个字,即32byte,自地址0040:001E开始。,但出于判断“对列满”的考虑,它最多只能保存15个键盘信息。当缓冲区满时,系统将不再接受按键信息,而会发出“嘟”的声音,以示要暂缓按键。
cnhnyu
[第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
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved