Intel 80286(インテル 80286)はインテルの16ビットマイクロプロセッサ (CPU)。IBMのPC/AT(日本ではPC-9800シリーズ)およびその互換機によって広く普及した、DOS時代の代表的なパーソナルコンピュータ (PC) 用プロセッサであった。

## 概要

1982年2月1日に発表、1984年から6MHz版と8MHz版が出荷された。134,000個のトランジスタを集積した1.5μmのNMOSプロセス(インテルの呼称だとHMOS-III)で製造され、性能を大幅に増加させるパイプラインを構成する4つの独立したユニット(アドレスユニット、バスユニット、命令ユニットと実行ユニット)を持っていた。クロック周波数は6、8、10、12MHz があった。パッケージには68ピンPLCC、LCC、PGAがあった。

8086とソフトウェアの上位互換性を持ち、より高速に命令実行可能(同クロック8086比で約2.5倍)。また、物理メモリ空間が16MBに拡張され、1GBの仮想記憶やマルチタスク処理に対応している。
また、インテルはこのモデルまではセカンドソース推進戦略を採用したため、AMD、富士通、シーメンス、ハリス・コーポレーション(以降、ハリスと表記)からもセカンドソース品が供給された。特にAMDとハリスは、ライセンスが受けられない80386に対抗するため、16、20MHz、ハリスは25MHz、といった、より高クロックの80286を市場に投入した。後述するようにDOSで動作させる限り、同一クロックの80386よりも高い実行速度が得られたからである。

インテル社のiAPX 286 Programmer's Reference Manualでは、CPUの80286と後述の周辺LSIの組み合わせがiAPX 286であるとしている。

## 対応ソフトウェア

8086や80186に対する上位互換性を持つリアルモードに加えて、プロセスやメモリを保護するプロテクトモードを追加し、これをサポートする命令が追加された。また、マルチタスクオペレーティングシステムを実装する際に必要な仕組みや命令群が拡張され、その後の32ビットCPUへ繋がる基礎ができあがった。4階層の特権レベル、仮想記憶機能、メモリ保護機能、TSS(Task state segment)を使用したタスクスイッチ機能などを持つ。

## リアルモードへの復帰

80286で、DOSやBIOSの資産を継承しつつ、更に仮想記憶機能を生かすためにはリアルモードとプロテクトモードの間を往復することが必要だが、80286にはプロテクトモードからリアルモードへの復帰命令が無く、復帰にはCPUのリセット信号線を有効にするしかなかった。そのため、80286搭載機では特定のI/Oポートを操作することによりCPUのリセットパルスを発生させるハードウェアを持っており、ソフトウェアからCPUのみのリセットを行うことができた。BIOSの初期化プログラムの中で通常のハードウェアリセット(電源ONまたはリセットスイッチ押下)と前述のソフトウェアリセットを区別し、初期化方法を切り替えるという処理が必要だった。これら一連の処理はオーバーヘッドが大きいため、結果的に80286を用いたリアル/プロテクトモード間のスイッチングは非効率的なものとなった。

なお後継の80386以降では、両モード間を任意に往復できる機能や仮想86モードなどを備えていた。

リアルモードへ戻るための方法はハードウェア独自のものとなっており、具体的な手順は以下のようにハードウェアによって異なる。

## HMAの活用

上記の通り80286はリアルモードとプロテクトモードを備えており、起動直後やMS-DOSでは基本的に8086や80186と互換性の高いリアルモードで動作する。

8086では1MiB(000000H - 0FFFFFH)のメモリ空間を持つが、本来16ビットのレジスタでは64KBまでのアドレス(00000H - 0FFFFH)しか表現できない。そこで16ビットレジスタを2つ用意し、まず1MB中のメモリ空間からアドレスの「原点」を10Hバイト単位で大雑把に指定し、もう1つのレジスタでそこから上位の64KBまでをアクセスできるようにしていた。したがって「原点」を示すセグメントレジスタを最大の0FFFFHに設定すれば、0FFFF0Hからさらに上位の64KBすなわち1MBを超える10FFEFHまでアドレスを表現できることになる。しかし8086ではアドレス線がA0 - A19の20本しか用意されていないため100000H - 10FFEFHのアドレスにはアクセスできず、桁あふれした部分は000000H - 0FFEFHにラップアラウンドしてアクセスすることになる。

80286ではこのようなラップアラウンドは起こらないため、インテル社のiAPX 286 Programmer's Reference Manualでは「もしリアルモードのプログラムがアドレス空間のラップアラウンドに依存している場合(例えばFFF0:0400 = 0000:0300)、上位アドレス4ビットをゼロにするために外部ハードウェアを使用すべきである」としている。

アドレス線を24本持つ80286を採用したシステム(PC/ATなど)では、ラップアラウンドを前提で作られたソフトウェアとの互換性を維持しつつ100000H以上のメモリにもアクセスできるように、21本目のアドレス線 (A20) の無効/有効を切り替えるハードウェアを持っていた。特定のI/Oポート(PC/ATではキーボードコントローラ)からA20を有効にするとリアルモードのままでも64Kバイト程度の上位メモリを参照することが可能になり、HMAと呼ばれた。

HMAは64Kバイト程度であるが640Kバイトの約10%にも相当し、メモリ枯渇に苦しむDOSユーザーにわずかな救いとなった。80386以降のプロセッサでもHMAは使用できる。

キャッシュを内蔵した80486以降のCPUではA20を無効にする機能を内蔵し、CPUにA20M#というピンを追加した。これは外部ハードウェアでA20を無効にしても80486がキャッシュに保存されたHMAにアクセスしてしまうためである。このA20M#を制御するのは、PC/ATではキーボードコントローラで変化していない。

なお、80286は16Mバイトの後ろの約64Kバイトにアクセスした場合、先頭の000000H番地にラップアラウンドにするが80386ではこのラップアラウンドは起こらない。このことが問題になる場合は、80386のページング機能を使用して16Mバイトの後ろの64Kバイトの領域を先頭の000000Hにマッピングすることで回避できる。

## 80286の判別

80286には`CPUID`命令は無く、インテルはフラグレジスタを使ったCPUの判別方法を紹介している。

`PUSHF`/`POPF`命令で読み書きできる16ビット分のフラグのうち、上位4ビットは8086世代(V30、80186などを含む)では使われていない予約ビットとなっていた。実際はその部分が1111bとして読み出せたものの、変更はできなかった。80286ではこの部分がプロテクトモードで使われるようになったため、リアルモードではゼロクリアされた状態になった。さらに仮想86モードを持つ80386からはリアルモードにおいてもこのビットが変更可能な仕様になっている。すなわちリアルモードの時点 (BIOSやMS-DOS) において、フラグレジスタのbit15-12が1111bから変更できなければ8086世代、0000bから変更できなければ80286、そのどちらでもない、つまり一部でも変更可能であれば80386以降と判断できる。

## 追加命令一覧

8086から使用できる基本命令セットに加え、以下の命令セットが追加された。

### 一般命令

80286で新たに追加された命令のうち11個の拡張命令セットは、後に発表された80186にも採用され、共通で使用できた。このほか既存の命令では`IMUL`と`PUSH`に即値(イミディエイト)が指定できるようになり、シフト・ローテイト命令ではCLレジスタを介さずに 1 以外の値を直接指定できるようになった。これらは80186でも同様である。

### システム命令

80286で追加されたシステム制御/プロセッサ制御の命令はいずれもプロテクトモードないしは80287関連の命令である。このほか既存命令としてはI/O(入出力)命令の類もシステム制御に使われる命令であり、プロテクトモードでは特権命令の扱いになった。HLTも特権レベルに依存するシステム命令となった。

SGDT, SIDT, SLDT, STR, SMSWは特権命令ではなく、アプリケーションプログラムからも実行可能である。このことは30年以上続いている。インテルは、CPUIDでUMIP(User-Mode Instruction Prevention)ビットがセットされているCPUではこれらの命令を特権命令にする機能を持つとしている。

### 廃止された命令

80286ではPOP CS命令(オペコード 0F)は廃止された。80186/V30も同様である。このオペコードは、80286以降、拡張命令のプリフィックスとして使用された。80286で使われている0Fプリフィックスは、上記のシステム命令のうち、ARPL以外の15命令が該当する。

### 非公開命令

80286の非公開命令であるLOADALLを使用するとリアルモードのままで、プロテクトメモリを含む16Mバイトのメモリにアクセス可能となる。

### 既存命令の仕様変更

80286はリアルモードにおいて8086や80186と高い互換性を持つものの、完全に等価というわけではない。異なる点としては、80286以降では`PUSH SP`命令の挙動が変更されている。また既存命令の組み合わせであっても、プロテクトモード上では挙動の異なる場合がある。

このほか変更点として、シフト・ローテイト命令で指定できるCLレジスタの値や即値が31以下に限定されるようになった。指定できる値は8ビットだが、実際には下位5ビット分しか使われない。この変更は80186も同様だが、V30では適用されておらず、8086相当の挙動となる。例えばシフト命令で31(16進数で0x1F)を超える値を指定した場合、8086やV30では演算結果が必ずゼロになるが、80186/286以降では32で割った余剰の分だけシフト演算される。

除算エラー(割り込み0)が発生した場合、スタックに保存されるCS:IPは8086では除算エラーを発生させた次の命令を指しているが、80286では除算エラーを発生させた命令自身を指している。

8086ではFPU命令の実行中は`WAIT`命令でCPUを止めておく必要があったが、80186以降ではその必要が無くなった。また、`LOCK`命令はもともとあらゆる命令においてバスをロックできる仕様だったが、80286以降ではロックできる命令とできない命令が決められている。

## 新しいレジスタ

### システムレジスタ

GDTR (Global Descriptor Table Regsister)

IDTR (Interrupt Descriptor Table Regsister)

LDTR (Local Descriptor Table Regsister)

TR (Task Register)

### フラグレジスタ

16bitあるフラグレジスタのうち、bit0からbit11までの12ビットは8086と同様のものが用意されている。前述の通り80186以前では上位4ビットが使われていなかったが、80286ではマルチタスクOSを想定した新たなフラグが追加されている。

なおbit15は予約ビットになっており、80286では不定(80386以降は0)とされている。

### MSW

80286ではMSW (Machine status word) レジスタが追加された。MSWを読み書きする`LMSW`、`SMSW`という専用の命令が用意されている。MSWは16bit分あるが、80286で定義されているのは下位4ビット分だけである。80386以降では新たに設けられたコントロールレジスタに統合され、CR0レジスタの下位16ビットが該当するが、互換性のためMSWとしてもアクセスできる。

## 割り込み

8086では割り込みは、割り込み4まで定義されており、80286では割り込み5以降が追加された。割り込み5から31まではインテル予約済みであったが、IBM PCでは割り込み8から15までを8259A経由の外部割込みに割り当てていた。プロテクトモードのOS/2などは8259Aの割り込み番号を別の値に変更する。

- 割り込み0:除算エラー

- 割り込み1:シングルステップ割り込み
- 割り込み2:NMI(マスク不可能割り込み)
- 割り込み3:ブレークポイント割り込み
- 割り込み4:INTOオーバーフロー
- 割り込み5:バウンドチェック

- 割り込み6:無効オペコード
- 割り込み7:コプロセッサ不在

- 割り込み8:ダブルフォルト

- 割り込み9:コプロセッサ・セグメント・オーバーラン
- 割り込み10:無効タスク・ステート・セグメント
- 割り込み11:セグメント不在

- 割り込み12:スタック・フォルト
- 割り込み13:一般保護例外

- 割り込み14 - 15:インテル予約済み
- 割り込み16:コプロセッサ・エラー

- 割り込み17 - 31:インテル予約済み

## ディスクリプターキャッシュ

80286ではセグメントレジスタには可視部とディスクリプターキャッシュ部があり、プログラムから直接 ディスクリプターキャッシュ部の変更はできない。プロテクトモードでは、セグメントレジスタの値の変更時に、グローバルディスクリプターテーブル、またはローカルディスクリプターテーブルからディスクリプターキャッシュ部にアクセス権、ベースアドレス、セグメントリミットが読み込まれ、実際のメモリアクセスはディスクプターキャッシュ部が使われる。

リアルモードでは、セグメントレジスタの値の変更時に、セグメントレジスタの内容が16倍されたものがディスクリプターキャッシュ部のベースアドレスにロードされ、実際のメモリアクセスはディスクプターキャッシュ部が使われる。このためリアルモードからプロテクトモードに移行した直後、セグメントレジスタの値がプロテクトモードでは不正な値でもハングアップや例外は発生しない。

また、80286は電源ONまたはリセット後、コードセグメントのディスクリプタキャッシュ部は、ベースアドレスがFF0000Hに設定され、IPはFFF0に設定されるので、FFFFF0Hから実行が開始される特殊なリアルモードで始まる。この特殊な状態はCALL FAR, JMP FAR命令などでセグメントレジスタが更新されるまで続く。

| 可視部 | ディスクリプターキャッシュ部 | | |
| --- | --- | --- | --- |
| セグメントレジスタ | ベースアドレス(24ビット) | アクセス権(8ビット) | セグメントリミット(16ビット) |

## 周辺LSI

- 80287 NPX

- 82284 クロック生成器
- 82288 バスコントローラ
- 82289 バス調停器
- 8259A 割り込みコントローラ

## CPUアクセラレータ

80286システムはCPUアクセラレータ製品により、より上位のプロセッサが利用できる場合があった。その際、486相当の製品は起動後にソフトウエアでCPUキャッシュを有効にすることで高速化させる必要があった。80286システムは16ビットバスであるため、外部16ビットであるi386SXにピン互換のCyrix Cx486SLC登場後は、これを用いた80286用のCPUアクセラレータ製品が各社から登場した。特に日本で主流だったPC-9800シリーズおよびEPSON PC-286シリーズでは80286をソケット経由で実装した機種が多く、CPU交換が容易だった。結果的にV30や後のi386SXと比べてCPUのアップグレードパスに恵まれ、様々なバリエーションのCPUアクセラレータ製品を生んだ。

- ABM 486GT-Xは前述のような486互換プロセッサを80286ピン互換のワンチップサイズに封入したもので、CPUアクセラレータと言うより80286ピン互換CPUに近いものだった。
- CPUアクセラレータ基板上でCyrix Cx486DLCのような外部32ビットプロセッサを動かす製品も存在した。
- メルコはシステムバスのクロックに関係無く独立クロック動作する製品も出していた。
- 最終的にメルコやアイ・オー・データ機器から発売されていたIBM 486SLC2を用いた80286向け製品では最大4倍速(約50MHz)で動作した。