如何在中断处理程序中除以零?

Tu *_* Do 4 x86 assembly operating-system nasm

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

例如,我试图除以0来测试我的中断并调用我的中断处理程序.然而,由于DIV指令未成功执行,EIP不会更新到之后的下一个指令,并从中断处理程序返回后用iret,它可以追溯到错误的div指令一次.

  mov ax, 3
  mov dl, 0
  div dl    ; go back here again and again
Run Code Online (Sandbox Code Playgroud)

处理此中断的正确方法是什么?我想到的几种方式:

  • 变化dl比0.但是其他别的东西,我不知道如果dl一旦有事能保持,并中断程序应该退出后恢复寄存器,而我不认为默默地提供错误的计算是很好的纠正错误.

  • 之后检索下一条指令div.但是,我没有想到任何简单可靠的方法来获取下一条指令.

  • 修改当前包含返回地址的一些其他的代码地址堆栈的顶部.所以,我们不再回到div教学了.

dav*_*ave 6

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

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

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


Bre*_*dan 5

一般来说,对于编码错误只有两种选择:

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

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