简体   繁体   中英

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.

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM