首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >8086汇编INT 9h :键盘ISR实现

8086汇编INT 9h :键盘ISR实现
EN

Stack Overflow用户
提问于 2016-09-30 02:44:32
回答 1查看 1.4K关注 0票数 2

当按下键时,我试图覆盖默认中断。下面是我的代码:不要调用kbd_handler并更改“port60”,我如何解决这个问题?你觉得是什么引起的?

代码语言:javascript
复制
 MAIN SEGMENT PUBLIC                        
         ASSUME CS:MAIN, DS:DATA

         MOV AX, MAIN   ; Set up the Data Segment address
         MOV DS, AX
         mov bx, 9 * 4 ;find the int 9

         mov dx, word ptr [bx]
         push dx
         mov dx, word ptr [bx] + 2    
         push dx


         mov ax, DATA
         mov DS, ax
         mov es, ax

         ;mov bx, 09h * 04h
        mov bx, 9 * 4 ;find the int 9 
         cli                    ; disable an interrupt
         mov word ptr [bx],  offset kbd_handler ; load your keyboard ISR
         mov word ptr [bx] + 2, seg kbd_handler ;
         sti                    ;enable interrupts      

    TEST_2 :
        call printc
        call delay_cx
        jmp test_2

         mov ax, MAIN
         mov dx, ax

         mov bx, 09h * 04h ;find the int 9

         cli ; disable interrupt
         pop dx
         mov word ptr [bx], dx ;back to normal address
         pop dx
         mov word ptr [bx]+2, dx
         sti ; enalbe interrupts  

         MOV AH, 4CH                        ;
         INT 21H                  

    PUBLIC    kbd_handler

    kbd_handler PROC    NEAR
         push ax
         push bx
         push cx
         push dx                                          
         push sp
         push bp
         push si
         push di

         in al, 64h
         test al, 01h

         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
         in al, 60h
         mov byte ptr ds:[port60], al   
         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

         mov al, 20h
         out 20h, al

         pop di
         pop si
         pop bp
         pop sp
         pop dx
         pop cx
         pop bx
         pop ax    
         IRET
    kbd_handler ENDP

    PRINT PROC NEAR
        CLD ; 
    PRINT_1 :
        MOVSB
        MOV AL, DL
        STOSB
        LOOP PRINT_1
        RET
    PRINT ENDP

    delay_cx proc   near            ; 
    delay_1:        
        push    cx          ; 
        mov cx, 50          ; 
    delay_2:
        loop    delay_2         ; 
        pop cx          ; 
        loop    delay_1         ;
        ret             ; 
    delay_cx    endp


    PRINTC PROC NEAR
        MOV AL, port60
        MOV DL, AL
        MOV AH, 02H
        INT 21H
        RET
    PRINTC ENDP

    MAIN ENDS

    DATA SEGMENT
        msg1 db 'Press and hold ESC'
        msg2 db 'ESC pressed, release ESC'
        msg3 db 'ESC released'
        kbdbuf      db 128 dup (0)
        port60    db    '1'
    DATA ENDS

    END  
EN

回答 1

Stack Overflow用户

发布于 2016-09-30 16:49:42

在代码中发现了几个错误:

  • 要检索和恢复中断向量,需要将您选择的段寄存器设置为零。迈克尔·佩奇也说了同样的话。所以让我们使用ES段寄存器。 ..。采购产品xor dx,dx mov es,dx mov dx,word ptr es:bx .
  • 当您在堆栈上保存中断向量时,您必须以相反的顺序恢复它!你的做法正好相反。
  • 在新的处理程序中,您只能使用CS段寄存器作为直接的覆盖。 在al中,60h移动字节ptr :port60 60,al
  • 不打算更改的推送/弹出寄存器是没有用的。此外,push sppop sp一直是红色的。
  • 由于您的主程序循环使用无条件跳转,所以代码将无法恢复正常运行。 TEST_2 :调用printc调用delay_cx jmp test_2 mov ax,MAIN <--您的代码永远不会到达这里!mov dx,ax
  • 使用call delay_cx时,仍然需要将CX寄存器设置为适当的值。

我看到你的计划还在进行中。很多不再使用的临时代码。删除不需要的东西,以免在可读性上松懈。

看看您所写的消息,我敢建议您以某种方式对这些信息进行划界。

代码语言:javascript
复制
msg1 db 'Press and hold ESC',13,10,0
msg2 db 'ESC pressed, release ESC',13,10,0
msg3 db 'ESC released',13,10,0
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39782865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档