Intel 80286

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

1. 概要
-----

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

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

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

2. 対応ソフトウェア
-----------

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

PC DOSおよびMS-DOSIBMが1984年にPC/XTの後継機種PC/ATを発表したとき、8086/8088とリアルモード互換性を持つ80286を採用した。しかし、プロテクトモードを活かして設計されたオペレーティングシステムは一般向けに普及しておらず、80286はもっぱら高速な8086としてPC-DOS  上で利用されることが多かった。DOS/V前述の通りPC/ATは80286機であるため、AT互換機用の日本語OSであるDOS/Vは80286以上のシステムが前提となっている。Windows 3.xWindows 3.0や英語版Windows 3.1において、いずれもスタンダードモードでは、80286のプロテクトモードが活用された。Windows 3.0の発売は、IBM PC/ATの発売から6年後の1990年であった。日本語版Windows 3.1以降、およびWindows for Workgroups 3.11以降は80286には対応していない。OS/2 1.xPC DOSおよびMS-DOS後継のプロテクトモード用オペレーティングシステムとしてIBMとマイクロソフトが共同開発したが、パソコン用OSのひとつとしての地位を獲得するにとどまった。OS/2 1.0の発売は、IBM PC/ATの発売から3年後の1987年であった。OS/2 2.0以降は80286には対応していない。XENIXマイクロソフトによって開発されたUNIXである。

3. リアルモードへの復帰
-------------

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

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

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

IBM PC/AT80286を搭載したIBM PC/ATではキーボードコントローラのI/Oにリセット機能が搭載されていた。これはI/Oポート64hにあり、通例はFEhを書き込みそのbit0を0にすることでリセット動作となる。これに先立ち当該プログラムはリセット後に処理を再開するアドレスCS:IPをBIOS Data Areaの0040:0067hに保存する。それ以外のスタックの位置などプログラムの動作継続に必要な情報は当該プログラム自身のデータ領域などに保存する。次にリセット後の動作を決めるシャットダウンコードをRTC用 不揮発性CMOSメモリのオフセット0FhにI/Oポート70h, 71hを使用して書き込む。5を書き込めばリアルモードへの復帰、0を書き込めば通常の電源ON、またはリセットスイッチ押下である。プロテクトモードから戻るとBIOSはBIOS Data Areaに保存したアドレスから当該プログラムの実行を再開させる。当該プログラムはあらかじめ保存しておいたスタックの位置などの情報を戻す。NEC PC-9800シリーズPC-9800シリーズでは1986年に登場したPC-9801VXに80286とV30の両方が搭載され、このとき80286とV30を切り替えるためのリセット用I/Oポートが設けられている。該当機ではI/O 00F0hに0を出力することでCPUがV30に切り替わらずにリセットされるが、これに先立ちリセット後に処理を続行するか再起動するかを事前に設定しておく必要がある。この設定はI/O 0035hのbit5,7にあり、再起動の場合は両方のbitを1に、処理続行の場合はbit7を0に設定する。処理を続行する場合は事前に戻りアドレスとなるCS:IPをスタックに保存したうえで、そのスタックの位置をメモリアドレス0000:0404から0407までの4バイトに保存しておく必要がある。

4. HMAの活用
---------

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

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

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

アドレス線を24本持つ80286を採用したシステムでは、ラップアラウンドを前提で作られたソフトウェアとの互換性を維持しつつ100000H以上のメモリにもアクセスできるように、21本目のアドレス線  の無効／有効を切り替えるハードウェアを持っていた。特定のI/Oポートから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にマッピングすることで回避できる。

5. 80286の判別
-----------

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

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

6. 追加命令一覧
---------

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

6.1. 一般命令
---------

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

6.2. システム命令
-----------

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

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

LGDT … Load Global Descriptor Table Register SGDT … Store Global Descriptor Table Register LIDT … Load Interrupt Descriptor Table Register SIDT … Store Interrupt Descriptor Table Register LLDT … Load Local Descriptor Table Register SLDT … Store Local Descriptor Table Register LAR … Load Access Right LSL … Load Segment Limit ARPL … Adjust Requested Privilege Level VERR … Verify Read Access VERW … Verify Write Access LTR … Load Task Register STR … Store Task Register CLTS … Clear Task Switched Flag LMSW … Load Machine Status Word SMSW … Store Machine Status Word

6.3. 廃止された命令
------------

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

6.4. 非公開命令
----------

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

6.5. 既存命令の仕様変更
--------------

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

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

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

7. 新しいレジスタ
----------

7.1. システムレジスタ
-------------

GDTR 

IDTR 

LDTR 

TR 

7.2. フラグレジスタ
------------

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

IOPL  フラグbit12・13を用いる2ビット分のフラグで、0から3までのフラグ状態を持ち、いわゆるIO特権レベルを表す。通常はPOPF命令でなければ変更できない。NT  フラグbit14。裏のタスクが有効であることを示すフラグ。割り込みなどで呼び出された場合に1となり、これによりIRET命令でのリターン処理の動作が変わる。なおbit15は予約ビットになっており、80286では不定とされている。

7.3. MSW
--------

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

PE MSWのbit0。プロテクトモードであることを表す。このbitをセットすることでプロテクトモードになる。MP MSWのbit1。FPUが存在する場合にセットされる。EM MSWのbit2。このビットがセットされているとFPUが無い扱いになる。TS MSWのbit3。タスク切り替え時にセットされる。

8. 割り込み
-------

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

割り込み0：除算エラー除算命令で0で割ろうとした場合や商が大きすぎてレジスタに収まらない場合に発生する。
割り込み1：シングルステップ割り込み
割り込み2：NMI(マスク不可能割り込み）