在中断处理程序中除以零怎么办?

时间:2015-10-09 03:32:04

标签: assembly x86 operating-system nasm

操作系统中断处理程序应该对与编码错误相关的中断做些什么?

例如,我试图除以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指令了。

2 个答案:

答案 0 :(得分:6)

你是对的,在这个特定的中断情况下,这些都不是特别好的事情。正如评论中所提到的,因为你有指令的地址,你可以获取该地址的任何内容,解码指令,然后将指针前进到下一个地址....但代码不会期望!

在POSIX操作系统中,SIGFPE信号涵盖了这种特殊行为。如果您正在编写操作系统并希望遵循POSIX,那么您的中断处理程序应该将该信号发送给进程。如果进程有一个该信号的处理程序,那么跳转到那个并允许进程处理它(例如,高级语言中的try / catch块可以工作的方式......现在你知道为什么异常很慢!)。如果没有信号处理程序,则应该终止该进程(并重新进入您的调度程序以确定下一步该做什么......并希望它是PID 1!)。

当然,这是你的操作系统,如果你不想,你没有理由你必须遵循POSIX!如果你有一些其他奇特的方法来处理用户程序中的错误,那么你可以实现它。

答案 1 :(得分:4)

通常,对于编码错误,只有两种选择:

a)终止流程。这可能包括也可能不包括做其他事情(记录错误,创建核心转储等)。

b)允许进程(甚至无法正常执行)尝试自己的恢复(这比正常执行更难做和测试)。一个例子就是信号。