Search code examples
assemblyinterruptx86-16isr

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


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.


Solution

  • 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".