2011-02-15 9 views
10

EXCEPTION_INT_OVERFLOWおよびEXCEPTION_INT_DIVIDE_BY_ZERO例外に関する質問があります。Win32 EXCEPTION_INT_OVERFLOW対EXCEPTION_INT_DIVIDE_BY_ZERO

WindowsはIDIV命令で生成された#DEエラーをトラップし、これらの2つのコードの1つで生成およびSEH例外を終了します。

私が持っている質問は、どのように2つの条件を区別するのですか?インテルマニュアルのidivに関する情報は、 "ゼロ除算"と "アンダーフローのケース"の両方で#DEを生成することを示しています。

intelマニュアルの第3巻の#DEエラーに関するセクションを簡単に見ましたが、私が収集できるベストは、OSがDIV命令をデコードし、除数引数をロードしてから比較する必要がありますゼロにする。

私は少し狂っているようです。なぜチップデザイナーは、エラーの2つの原因を区別するために何らかのフラグを使用しませんでしたか?私は何かが欠けているように感じる。

OSが2つの異なる原因を区別する方法を知っている人はいますか?

+1

「IDIV」が「EXCEPTION_INT_OVERFLOW」を生成できることを示す文書がありますか?私は 'INT_MIN/-1'には問題があると理解していますが、' EXCEPTION_INT_OVERFLOW'の記述にはこのケースは含まれていません。 –

+0

@Ben実験的に検証しました。 INT_MIN/-1を実行すると、IDIV命令はEXCEPTION_INT_OVERFLOWになり、INT_MIN/0を実行するとEXCEPTION_INT_DIVIDE_BY_ZEROが得られます。どちらの場合も、IDIV命令の実行を試みた後に例外がスローされます。 –

+0

@Scott:Hmmm ... MSDNのドキュメントが失敗します。それは珍しいことではありません。 –

答えて

6

あなたの前提は正しいと思われます。 #DEで利用できる唯一の情報は、指示を与えるCSとEIPです。 2つのステータスコードが異なるため、OSは命令をデコードしてどちらを決定する必要があります。

また、ゼロで割った値が無限大で、宛先レジスタに収まりきらないため、チップメーカはこのケースに対して2つの別々の割り込みを必要としないことをお勧めします。

「分かっている」ということは、分かりやすくするために、知っている人は誰でもその人を悪用しないようにすることは許可されていない可能性があります(カーネルモードへのジャンプは良い方法です悪用しようとすることを開始すること)、または通知なしに変更される実装の詳細に基づいて前提を作ること。


編集

は、私は、少なくとも私はへのアクセスを持っていたのWindows XP(32ビット)の特定のバージョンにそれを言うことができKDでプレイした(とプロセッサは、それが上で実行されていた) nt!Ki386CheckDivideByZeroTrap割り込みハンドラ命令のModRM値をデコードして STATUS_INTEGER_DIVIDE_BY_ZEROまたは STATUS_INTEGER_OVERFLOWを返すかどうかを判断するように見えます。

(もちろん、これはオリジナルの研究で、どこでも、誰が保証し、また、インテルのマニュアルに基づいて行うことができる控除を一致させるために起こるされていません。)

+0

実装方法を理解する以外には何も探していません。私は命令を手動でデコードして引数をロードすることで実装できることは知っていますが、これを行うには奇妙な方法のように思えます。 –

+0

@Scottプロセッサは、命令の解読とは別にそれを検出する手段を提供していないので、代替手段はありません。インテルのドキュメントによると、状態の変更はなく、EIPは命令を超えて進んでいないという。私は、これが関連しているケースが2回以上あると考えています(違法オペコードが最も可能性があります)。いずれの場合でも、ModRM値のデコードはそれほど難しくありません。カーネルにはその機能があります。 – Zooba

+0

私はそれが難しくないことを知っています。それは単にそれを行う効率的な方法のようです。おそらく、それほど悪くはない、スタックウォークをすることと比べると。いずれにせよ、私はインテルマニュアルのページ(#DEについてのもの)を読んで、「彼らは命令を解読する必要があります、それは興味深い」と考えました。私はそれが本当に何をしているのか知りたかったのです。 –

1

Zoobaの答えは、Windowsが見つけるために命令を解析し、まとめたもの何を上げるか。

しかし、あなたはルーチンがコードを正しく選択することに頼ることはできません。

私は、64ビットDIV命令と64ビット版のWindows 7上で次のことを観察:オペランド(除数)は関係なく、引数の値の、それは常にEXCEPTION_INT_DIVIDE_BY_ZEROを発生させ、メモリオペランドである場合

  • オペランドがレジスタで、下位ワードがゼロの場合、上半分がゼロでないかどうかにかかわらず、EXCEPTION_INT_DIVIDE_BY_ZEROが発生します。

これを見つけるために1日かかりました...これが役立つことを願っています。

関連する問題