Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 8086汇编INT 9h:键盘ISR实现_Assembly_X86 16 - Fatal编程技术网

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

Assembly 8086汇编INT 9h:键盘ISR实现,assembly,x86-16,Assembly,X86 16,我试图在按键时覆盖默认的中断。 下面是我的代码:不要调用kbd_处理程序并更改“port60” 我如何解决这个问题?你认为是什么引起的 MAIN SEGMENT PUBLIC ASSUME CS:MAIN, DS:DATA MOV AX, MAIN ; Set up the Data Segment address MOV DS, AX mov bx, 9 * 4 ;f

我试图在按键时覆盖默认的中断。 下面是我的代码:不要调用kbd_处理程序并更改“port60” 我如何解决这个问题?你认为是什么引起的

 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  

在代码中发现多个错误:

  • 要检索和恢复中断向量,需要将所选的段寄存器设置为零。迈克尔·佩奇也说了同样的话。因此,让我们使用
    ES
    段寄存器

    ...
    xor dx, dx
    mov es, dx
    mov dx, word ptr es:[bx]
    ...
    
  • 在堆栈上保存中断向量时,必须按相反顺序还原它!你的做法正好相反

  • 在新的处理程序中,您只能直接使用
    CS
    段寄存器作为覆盖

    in al, 60h
    mov byte ptr cs:[port60], al 
    
  • 推送/弹出不打算更改的寄存器是没有用的。此外,
    push sp
    pop sp
    始终是冗余的

  • 由于主程序循环使用无条件跳转,因此用于恢复正常的代码永远不会运行

    TEST_2 :
     call printc
     call delay_cx
     jmp test_2
    
     mov ax, MAIN  <-- You're code will never get here!
     mov dx, ax
    

    浏览这个-第一件让我感到奇怪的事情是
    mov-dx,word-ptr[bx]
    用于检索和更新中断向量
    mov-dx,单词ptr[bx]
    表示DS,因此与
    mov-dx,单词ptr-DS[bx]
    相同。您已将DS设置为MAIN的段。问题是中断向量表从地址0x0000:0x0000开始。在中断表中更新/读取值时,应考虑将ES设置为0,然后使用段覆盖。如果您将ES设置为零,那么您应该能够执行类似于
    mov-dx,word ptr-ES:[bx]
    这在新处理程序中是正确的,您只能直接使用CS段寄存器作为覆盖。问题是,在他的代码中,他有单独的代码段和数据段。如果该代码中的CS=DS,则覆盖就可以了,但是如果CS!=DS然后简单地使用CS重写可能不起作用。我不知道他在建立什么记忆模型,很难说。
    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