程序在ISR后继续返回同一行。 (大会8086)

时间:2016-01-10 09:56:15

标签: assembly interrupt x86-16 isr

我正在处理中断,我在运行代码时遇到了这个问题:

DATA SEGMENT
    INPUTV DW 0035H, 0855H, 2011H, 1359H
    OUTPUTV DB 4 DUP(0)
    DIVIDER DB 09
    ERROR_FLAG DB 0
DATA ENDS

_STACK SEGMENT STACK
    DW 100 DUP(0)
    TOP_STACK LABEL WORD
_STACK ENDS

CODE SEGMENT
    ASSUME CS:CODE, DS:DATA, SS:_STACK
MAIN:
    MOV AX, _STACK
    MOV SS, AX
    MOV SP, OFFSET TOP_STACK
    MOV AX, DATA
    MOV DS, AX

    MOV AX, 0000H
    MOV ES, AX
    MOV WORD PTR ES:0002, SEG INT_PROC  ;PUSHING CS TO STACK
    MOV WORD PTR ES:0000, OFFSET INT_PROC   ;PUSHING IP TO STACK

    MOV SI, OFFSET INPUTV
    MOV BX, OFFSET OUTPUTV

    MOV CX, 4H
REPEAT:
    MOV AX, [SI]
    DIV DIVIDER
    CMP ERROR_FLAG, 1H
    JE ERROR_ENCOUNTER
    MOV [BX], AL
    JMP SKIP
ERROR_ENCOUNTER:
    MOV BYTE PTR [BX], 0H
    MOV ERROR_FLAG, 0H
SKIP:
    ADD SI,2
    INC BX
    LOOP REPEAT
    INT 3H
CODE ENDS

INT_SEG SEGMENT 
    ASSUME CS:INT_SEG
INT_PROC PROC
        MOV ERROR_FLAG, 1
        IRET
    INT_PROC ENDP
INT_SEG ENDS

END MAIN

程序从IRET指令

返回ISR(此处为INT_PROC)后
    INT_PROC PROC
            MOV ERROR_FLAG, 1
            IRET

正在执行以下行:

    DIV DIVIDER

一次又一次地应该去:

    CMP ERROR_FLAG, 1H

Debugging Image Here

我在论坛中也发现了这一点:

Where the program counter goes after returning the interrupt handler?

为什么会发生这种情况,我该如何解决?请帮忙。

2 个答案:

答案 0 :(得分:2)

x86架构定义了三类软件生成的中断:

  • 陷阱,明确且有意地调用了中断。这些通常是INT指令的结果,并不表示问题本身。推送的IP是以下指令的IP,因此在返回处理程序之后,不会重试该指令。如果没有办法解决问题,它可能会杀死进程。
  • 错误,例如页面错误和除零。这些表明不可完成的指令。推送的IP是产生故障的指令的IP;中断处理程序有机会尝试清理(最常见的是,通过在内存页面中分页导致页面错误),然后重试指令。
  • 中止,这是一种基本上无法恢复的异常类型的错误(除非通过终止进程)。中断处理程序不应该返回。

在除以零的情况下,在除法之后恢复不是一个好的响应,因为这样就跳过了一条指令。实际上,这些更像是堕落而不是缺点。不应该使用中断处理程序来破解“替代行为”。

答案 1 :(得分:1)

执行IRET时,CPU将再次执行导致异常的指令。例如,这对于处理页面错误非常有用。

您应该在异常处理程序中的异常上修改存储在堆栈上的IP的值,以便CPU执行所需的指令。