6

256 のエントリを持つ idt テーブルをロードしました。すべて同様のハンドラを指しています。

  • 例外 8 および 10 ~ 14 の場合は、例外番号をプッシュします (これらの例外はエラー コードを自動的にプッシュします)。
  • その他の場合は、「ダミー」エラー コードと例外番号をプッシュします。
  • 次に、共通ハンドラにジャンプします

したがって、共通ハンドラーが入ると、スタックは適切に配置され、例外/割り込み番号、エラー コード (単なるダミーの可能性があります)、eflags、cs、および eip が含まれます。

私の質問は、割り込みハンドラからの復帰に関するものです。以前はiretスタックから例外番号とエラー コードを取り出してリターンしていましたが、例外番号 8 では機能しません。スタックにエラー コードを残すと、正常に返されます。

質問:

  • エラーコードをそこに置く例外のために、エラーコードをスタックに残す必要がありますか? iretもしそうなら、エラーコードをポップする必要があるかどうかをどのように判断しますか?
  • 割り込みを有効にするとすぐに、常に例外 8 (二重障害) が発生しますが、その後はすべて正常に動作します (私は趣味の OS を開発しています)。これは正常な動作ですか、それともどこかにバグがありますか?
4

4 に答える 4

13

CPU がエラー コードを自動的にプッシュした場合、ハンドラーiret. 命令は、それが障害、トラップ、または外部割り込みであるかどうか、どこから来たのiretかを知りません。常に同じことを行い、スタックにエラー コードがないことを前提としています。

SDM (Software Developer's Manual)、第 3 巻、第 5 章、セクション 5.13 のエラー コードからの引用:

エラー コードは、(デフォルトの割り込み、トラップ、またはタスク ゲート サイズに応じて) ダブルワードまたはワードとしてスタックにプッシュされます。ダブルワード プッシュに対してスタックをアラインしておくために、エラー コードの上位半分が予約されています。IRET 命令を実行して例外ハンドラから復帰する場合、エラー コードはポップされないことに注意してください。そのため、ハンドラは復帰を実行する前にエラー コードを削除する必要があります。

IA-32 ソフトウェア開発者マニュアル 、http : //www.intel.com/products/processor/manuals/にあります。

第 3 巻第 1 部の第 5 章では、例外と割り込みの処理について説明しています。ボリューム 2 パート 1 には、iret命令の仕様があります。

于 2009-01-29T13:50:57.160 に答える
1

しばらく前に小さなx86OSを作成しました。cvsリポジトリのファイルisr.asmを見てください。

ハンドラーの設定方法に注目してください。ほとんどの場合、エラーコードが自動的にプッシュされる少数のハンドラーを考慮して、ダミーのdwordをスタックにプッシュします。次に、iretを介して戻る場合、割り込みに関係なく、常にスタック上に2つのdwordを想定し、iretの前に8の追加espを実行して、問題を適切にクリーンアップできます。

それはあなたの最初の質問に答えるはずです。

2番目の質問については、割り込みを有効にすると二重の障害が発生します。正しく設定していない場合、ページングで問題が発生する可能性があります。他にも百万の可能性があります:)

于 2009-01-29T14:02:10.773 に答える
0

エラーコードをそこに置く例外のために、スタックにエラーコードを残す必要がありますか?

他の人が述べたように、次のいずれかを行う必要があります。

pop %eax
/* Do something with %eax */
iret

または、エラー コードを無視する場合:

add $4, %esp
iret

そうしないiretと、エラー コードが新しい CS として解釈され、ページ フォールト ハンドラーからの iret が割り込み 13 (一般保護フォールト) とエラー コード 0x18 を生成する理由で説明されているように、一般保護フォールトが発生する可能性があります。 ?

これを説明するために作成したこのページ ハンドラーの作業は最小限です。をコメントアウトしてみてくださいpop

上記を、スタックをポップしない分割エラー例外と比較してください。

int $14単純に を実行すると、余分なバイトがプッシュされないことに注意してください。これは実際の例外でのみ発生します。

Intel Manual Volume 3 System Programming Guide - 325384-056US 2015 年 9 月表 6-1. 「保護モードの例外と割り込み」列の「エラー コード」には、エラー コードをプッシュするかどうかの割り込みのリストが含まれています。

38.9.2.2「ページ・フォルト・エラー・コード」では、エラーの意味を説明しています。

これに対処する適切な方法は、0これを行わない割り込みのスタックにダミーのエラー コードをプッシュして、物事を統一することです。James Molloy のチュートリアルはまさにそれを行います。

Linux カーネル 4.2 も同様のことをしているようです。arch/x86/entry/entry64.S の下では、次のように割り込みをモデル化しhas_error_codeます。

trace_idtentry page_fault do_page_fault has_error_code=1

次に、同じファイルで次のように使用します。

.ifeq \has_error_code
pushq $-1 /* ORIG_RAX: no syscall to restart */
.endif

と押しhas_error_code=0ます。

于 2015-10-28T18:08:08.033 に答える