我对EXCEPTION_INT_OVERFLOW和EXCEPTION_INT_DIVIDE_BY_ZERO例外有疑问。
Windows将捕获IDIV指令生成的#DE错误,并最终使用这两个代码之一生成SEH异常。
我的问题是它如何区分这两个条件?英特尔手册中有关idiv的信息表明它将在“除以零”和“下溢情况”中生成#DE。
我快速浏览了intel手册第3卷中#DE错误的部分,我能收集的最好的是操作系统必须解码DIV指令,加载除数参数,然后比较它为零。
但这对我来说似乎有点疯狂。为什么芯片设计者不会使用某种标志来区分错误的两个原因?我觉得我一定错过了什么。
有谁知道操作系统如何区分两种不同的失败原因?
答案 0 :(得分:6)
您的假设似乎是正确的。 #DE上唯一可用的信息是CS和EIP,它提供指令。由于两个状态代码不同,OS必须解码指令以确定哪个。
我还建议芯片制造商在这种情况下不需要两个单独的中断,因为除以零的任何东西都是无穷大,这太大了,不适合你的目标寄存器。
至于“确切知道”它是如何区分的,所有知道的人都可能不被允许透露它,要么是为了阻止人们利用它(不完全确定如何,但跳进内核模式是一个好地方开始寻求利用)或根据可能在不另行通知的情况下改变的实施细节做出假设。
编辑:玩过kd之后我至少可以说在我可以访问的特定版本的Windows XP(32位)(及其运行的处理器){{ 1}}中断处理程序似乎解码指令的ModRM值,以确定是否返回nt!Ki386CheckDivideByZeroTrap
或STATUS_INTEGER_DIVIDE_BY_ZERO
。
(显然这是原始研究,任何地方的任何人都不能保证,并且恰好与基于英特尔手册的扣除相匹配。)
答案 1 :(得分:1)
Zooba的回答总结了Windows解析指令以找出要引发的内容。
但你不能依赖于例程正确选择代码。
我在64位Windows 7上使用64位DIV指令观察到以下内容:
我花了一天时间才发现这一点...希望这会有所帮助。