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