我正在处理中断,我在运行代码时遇到了这个问题:
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
我在论坛中也发现了这一点:
Where the program counter goes after returning the interrupt handler?
为什么会发生这种情况,我该如何解决?请帮忙。
答案 0 :(得分:2)
x86架构定义了三类软件生成的中断:
INT
指令的结果,并不表示问题本身。推送的IP是以下指令的IP,因此在返回处理程序之后,不会重试该指令。如果没有办法解决问题,它可能会杀死进程。在除以零的情况下,在除法之后恢复不是一个好的响应,因为这样就跳过了一条指令。实际上,这些更像是堕落而不是缺点。不应该使用中断处理程序来破解“替代行为”。
答案 1 :(得分:1)
执行IRET
时,CPU将再次执行导致异常的指令。例如,这对于处理页面错误非常有用。
您应该在异常处理程序中的异常上修改存储在堆栈上的IP
的值,以便CPU执行所需的指令。