Program keeps returning to same line after ISR. (Assembly 8086)

时光毁灭记忆、已成空白 提交于 2021-01-27 11:51:51

问题


I'm working with interrupts and I'm facing this problem while running my code:

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

After the program returns from the ISR (here INT_PROC) from IRET instruction

    INT_PROC PROC
            MOV ERROR_FLAG, 1
            IRET

it is executing the line:

    DIV DIVIDER

again and again while it was supposed to go to:

    CMP ERROR_FLAG, 1H

Debugging Image Here

I found this in the forum which also says the same:

Where the program counter goes after returning the interrupt handler?

why is that happening and how can i solve it? please help.


回答1:


The x86 architecture defines three classes of software-generated interrupts:

  • Traps, explicitly and intentionally invoked interrupts. These are usually the result of the INT instruction, and don't indicate a problem per se. The pushed IP is that of the following instruction, so following the return of the handler, the instruction is not retried. Or it could just kill the process, if there's no way to resolve the fault.
  • Faults, such as page faults and division by zero. These indicate an un-completable instruction. The pushed IP is that of the instruction generating the fault; the interrupt handler gets a chance to try to clear things up (most commonly, by paging in the memory page which led to the page fault), and then the instruction is retried.
  • Aborts, an unusual type of fault which is essentially unrecoverable (except by terminating the process). The interrupt handler should not return.

In the case of division by zero, resuming following the division isn't a good response, because then an instruction has been skipped. Really, these are more like aborts than faults. The interrupt handler should not be used to hack in "alternative behavior".




回答2:


When you execute IRET, the CPU will execute the instruction which is the cause of the exception again. This is useful for dealing with page fault, for example.

You should modify the value of IP stored on the stack on the exception in the exception handler so that the CPU will execute the desired instruction.




回答3:


Since the division exception is a fault, the saved CS:IP will point at the DIV instruction. Simply returning from the interrupt will re-execute the faulty instruction. The solution is to change the value for IP that's on the stack. The beauty of it is that you no longer need the ERROR_FLAG variable at all.

INT_PROC PROC
    pop  ax
    push ERROR_ENCOUNTER
    xor  ax, ax  ;Eliminates the need for the SKIP label and some instructions.
    iret
INT_PROC ENDP

Please note that it would have been wise to disable interrupts while setting up InterruptVector0.

MOV AX, 0000H
MOV ES, AX
cli
MOV WORD PTR ES:0002, SEG INT_PROC
MOV WORD PTR ES:0000, OFFSET INT_PROC
sti

Your loop could be this tight:

    MOV CX, 4H
REPEAT:
    MOV AX, [SI]
    DIV DIVIDER
ERROR_ENCOUNTER:
    MOV [BX], AL
    ADD SI, 2
    INC BX
    LOOP REPEAT


来源:https://stackoverflow.com/questions/34704121/program-keeps-returning-to-same-line-after-isr-assembly-8086

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!