操作系统中断处理程序应该对与编码错误相关的中断做些什么?
例如,我试图除以0来测试我的中断并调用我的中断处理程序。但是,由于div指令未成功执行,因此EIP不会更新到它之后的下一条指令,并且在从iret
的中断处理程序返回后,它会再次返回到错误的div
指令。 / p>
mov ax, 3
mov dl, 0
div dl ; go back here again and again
处理此中断的正确方法是什么?我想到的几种方式:
将dl
更改为0以外的其他内容。但是,如果发生某些事情,我不确定dl
是否可以保留,并且中断例程应该在退出后恢复寄存器,并且我不认为通过提供错误的计算来默默地纠正错误。
检索div
之后的下一条指令。但是,我没有想到任何简单可靠的方法来获得下一条指令。
将当前包含返回地址的堆栈顶部修改为其他一些代码的地址。因此,我们不再回到div
指令了。
答案 0 :(得分:6)
你是对的,在这个特定的中断情况下,这些都不是特别好的事情。正如评论中所提到的,因为你有指令的地址,你可以获取该地址的任何内容,解码指令,然后将指针前进到下一个地址....但代码不会期望!
在POSIX操作系统中,SIGFPE信号涵盖了这种特殊行为。如果您正在编写操作系统并希望遵循POSIX,那么您的中断处理程序应该将该信号发送给进程。如果进程有一个该信号的处理程序,那么跳转到那个并允许进程处理它(例如,高级语言中的try / catch块可以工作的方式......现在你知道为什么异常很慢!)。如果没有信号处理程序,则应该终止该进程(并重新进入您的调度程序以确定下一步该做什么......并希望它是PID 1!)。
当然,这是你的操作系统,如果你不想,你没有理由你必须遵循POSIX!如果你有一些其他奇特的方法来处理用户程序中的错误,那么你可以实现它。
答案 1 :(得分:4)
通常,对于编码错误,只有两种选择:
a)终止流程。这可能包括也可能不包括做其他事情(记录错误,创建核心转储等)。
b)允许进程(甚至无法正常执行)尝试自己的恢复(这比正常执行更难做和测试)。一个例子就是信号。