割り込みと例外は、現在実行中のプログラムやタスクから、実行を強制的に割り込みハンドラと呼ばれる処理に移行することを言います。
割り込みは通常、プログラムの実行中に、周辺装置へのサービス要求のような、プロセッサにとって外部的なイベントをハードウェアから要求を受けたときに起こります。また、ソフトウェアでも、INT n 命令を実行することにより割り込みを生成できます。
一方例外は、プロセッサが命令の実行中にゼロ除算のようなエラー条件を検出したときに発生します。プロセッサは、保護違反、ページ・フォルト、内部マシン・フォルトをはじめ、さまざまなエラー条件を例外として検出します。
コンピュータに限らず、実生活でも"割り込み"と言う現象は良く発生します。
あなたは今、ある仕事をしています。この仕事が終わらないと帰れないので、黙々と作業をこなしています。
その時、お客さんからの電話が鳴りました。あなたは面倒くさいなぁと思いながら、作業を中断して対応します。
そして対応後には、途中で中断した作業に戻ります。電話の内容によっては、別の仕事を優先さる必要が出てくるかも知れません。
このような事が、コンピュータの内部でも起きています。
例えば、コンピュータは何かの処理を実行中だとします。その時、あなたはマウスを移動させようとしました。
もし、割り込みが起らなかったら、マウスはこの処理が終わるまで動けなくなります。マウスが処理中でもちゃんと動くのは、マウス入力の割込みが発生して、コンピュータがそれを優先して処理しているからです。
ここで、「電話が鳴った」や「マウスを移動させた」などの割り込みが発生する要因となったものを、割り込み要因と言い、割り込みは要因の種類によって、ハードウエア割り込みとソフトウェア割り込みに大きく分けられます。
また例外は、書類を書いているときに「紙が無くなった」、「書き間違えた」、「コーヒーこぼした」などのエラー要因に、似ていると考えて良いでしょう。
Intel CPUには、ハードウエアからの割り込みを受けるための、INTRとNMIpinが2つあります。これらのピンにパスルが入るとCPUは、ハードウエア割り込みの処理を行います。なぜ2つのpinがCPUあるのでしょう?それぞれのpinは次のような意味を持つからです。
- INTR
- これらの割り込みは、eflagsレジスタのIFフラグをクリアすることで無効にできる、ソフトウェアでマスク可能な割り込みを発生させます。
- NMI(Non Maskable Interrupt)
- IFフラグをクリアしても無効にできない。ハードウェアの失敗のような、クリティカルなイベントのみがこれらの割り込みを発生させます。
CPUの外部に接続されている、キーボードやハードディス等のハードウエアデバイスからこれらのpinに対して、割込み信号を送ります。しかし、これらのデバイスは、互いに独立して接続されているので、デバイス同士で割込み信号を譲り合う事はできません。タイミングによっては、デバイス同士の割込み信号が同時に送信されることもあるかもしれません。そうなると割込み信号を取りこぼしたりして、信号のない交差点状態になってしまいます。
そこで、信号機の役目する割込みコントローラが登場します。
CPUの外部に接続されているデバイスは、割込み信号を譲り合う事はできないので、各信号を整理してCPUに伝えるのが割込みコントローラの役目です。PC/AT機には8259というPIC[Programmable Interrupt Controller]が2つ使われています。(x86アーキテクチャのマルチプロセッサ環境で使用するための割り込みコントローラ、APICなんてものが載っているマシンもあるらしい。)
ハードウエア割り込みの処理を大まかに説明すると次のようになります。
- PICは内部にIRR[Interrupt Request Register]を持っていて、各デバイスに繋がっています。デバイスから割込みを受けると、当該IRRレジスタがセットされ、CPUに対して割り込み要求を発生します。
- CPUは割り込みを受け付けると、INTA信号を2回出し応答します。
- PIC側では1回目のINTAでIRRに格納された割り込みのうち、どれがもっとも優先度が高いかを決定します。
- 優先度を確定したら、2回目のINTAパルスがきたときにデータ・バスにベクタ番号を出力します。
- CPUはベクタ番号を読み込み、それに対応した割込み処理を走らせます。
通常、優先度はIR0がもっとも高く、IR15がもっとも低くなっていて、次のようにアサインされています。
ハードウエア割り込み
IRQ番号 |
割込みデバイス |
IRQ0 |
システムタイマ (Intel 8253 or 8254 プログラマブルインターバルタイマ) |
IRQ1 |
キーボード |
IRQ2 |
PC/ATではスレーブの8259のINTにカスケード接続されている |
IRQ3 |
シリアルポートCOM2及びCOM4 |
IRQ4 |
シリアルポートCOM1及びCOM3 |
IRQ5 |
LPT2 |
IRQ6 |
フロッピーディスクコントローラ |
IRQ7 |
LPT1 |
IRQ8 |
リアルタイムクロック (RTC) |
IRQ9 |
割り当てなし |
IRQ10 |
割り当てなし |
IRQ11 |
割り当てなし |
IRQ12 |
PS/2 マウス |
IRQ13 |
数値演算コプロセッサ |
IRQ14 |
ハードディスクコントローラ1 |
IRQ15 |
ハードディスクコントローラ2 |
INT n 命令を使用し、割り込みベクタ番号をオペランドとして指定すると、ソフトウェア内部から割り込みを生成できます。例えば、INT 35 命令を実行すると、割り込み35 の割り込みハンドラが呼び出されます。
INT n 命令を使用してソフトウェアで生成された割り込みは、INTR割り込みと異なりEFLAGS レジスタのIF フラグではマスクできません。
例外は、プロセッサによって例外が検出された時におきる割り込みで、下記の3つに分けることができます。
- トラップ
-
トラップは、ソフトウェア上でINTO,INT 3 命令を実行することにより発生するソフトウェア例外です。トラップは、例外時に呼び出されるハンドラから戻ってきたときに、例外状態を検出した命令を再度実行しないタイプの例外です。
主な用途としては、プログラムのデバッグなどで使用されます。
- フォールト
-
フォールトは、命令を実行中に例外状態を検出した場合、発生する割込みです。フォールトは、例外時に呼び出されるハンドラから戻ってきたときに、例外状態を検出した命令を再度実行するタイプの例外です。
例えば、CPUで指定した範囲以外のメモリをアクセス/実行した場合、「一般保護違反」が発生します。
また、メモリが確保されていない領域をアクセスすると「メモリフォールト」が発生します。「メモリフォールト」の場合、呼び出された割込み処理で、メモリの割り付けを行う事によりオンデマンドなメモリ管理を行うOSもあります。
- アボート
- アボート、命令を実行中に致命的な例外状態を検出した場合、発生する割込みです。これが発生した場合、通常は処理を終了させます。
CPUは各例外と割り込みに、ベクタと呼ばれる識別番号を対応付けています。
ベクタ番号
ベクタ No |
内容 |
割込み要因 |
タイプ |
エラー コード |
0 |
除算エラー |
DIV およびIDIV 命令 |
フォルト |
なし |
1 |
デバッグフォルト |
任意のコード/ データ参照またはINT 1 命令 |
トラップ |
なし |
2 |
NMI 割り込み |
マスク不可能外部割り込み |
割り込み |
なし |
3 |
ブレークポイント |
INT 3 命令 |
トラップ |
なし |
4 |
オーバーフロー |
INTO 命令 |
トラップ |
なし |
5 |
BR BOUND の範囲外 |
BOUND 命令 |
フォルト |
なし |
6 |
無効オペコード (不明な命令) |
UD2 命令または予約オペコード |
フォルト |
なし |
7 |
デバイス使用不可 (数値演算コプロセッサ無し) |
浮動小数点命令またはWAIT/FWAIT 命令 |
フォルト |
なし |
8 |
ダブル・フォルト |
NMI またはINTR を生成できる任意の命令 |
アボート |
あり(0) |
9 |
コプロセッサ・セグメント ・オーバーラン(予約済み) |
フォルトなし浮動小数点命令 |
フォルト |
なし |
10 |
無効TSS |
タスク・スイッチまたはTSS アクセス |
フォルト |
あり |
11 |
セグメント不在フォルト |
セグメント・レジスタのロードまたはシステム・セグメントへのアクセス |
フォルト |
あり |
12 |
スタック・セグメント・フォルト |
スタック操作およびSS レジスタのロード |
フォルト |
あり |
13 |
一般保護フォルト |
任意のメモリ参照およびその他の保護チェック |
フォルト |
あり |
14 |
ページ・フォルトフォルト |
任意のメモリ参照 |
フォルト |
あり |
15 |
予約済み(使用禁止) |
|
|
なし |
16 |
浮動小数点エラー (数値演算フォルト) |
浮動小数点命令またはWAIT/FWAIT 命令 |
フォルト |
なし |
17 |
アライメント・チェック |
メモリ内の任意のデータ参照 |
フォルト |
あり(0) |
18 |
マシン・チェック |
モデルに依存 |
アボート |
なし |
19 |
ストリーミングSIMD 拡張命令 |
SIMD 浮動小数点命令 |
フォルト |
なし |
20-31 |
予約済み(使用禁止) |
|
|
|
32-255 |
ユーザ定義割込み |
外部割り込みまたはINT n |
割り込み |
|
0 から31 の範囲のベクタは、例外およびNMI 割り込みに割り当てられています。32から255の範囲のベクタは、ユーザ定義の割り込みとして指定されています。外部割込みは32から255のベクタに割り当てられます。