thumb|250px|right|Intel 80286 (PLCC) 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 ManualiAPX 286 Programmer's Reference Manual including the iAPX 286 Numeric Supplementでは、CPUの80286と後述の周辺LSIの組み合わせがiAPX 286であるとしている原文:iAPX 286 - 80286 CPU family Each processor family consists of the CPU(e.g., 80286), processor extensions(80287 for the iAPX 286), and bus support circuits, such as the 82284 Clock Generator and 82288 Bus Controller. 。

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

DOS(PC DOSおよびMS-DOS) IBMが1984年にPC/XTの後継機種PC/ATを発表したとき、8086/8088とリアルモード互換性を持つ80286を採用した。しかし、プロテクトモードを活かして設計されたオペレーティングシステムは一般向けに普及しておらず、80286はもっぱら高速な8086としてPC-DOS (MS-DOS) 上で利用されることが多かった。

DOS/V 前述の通りPC/ATは80286機であるため、AT互換機用の日本語OSであるDOS/Vは80286以上のシステムが前提となっている。

Windows 3.x Windows 3.0や英語版Windows 3.1において、いずれもスタンダードモードでは、80286のプロテクトモードが活用された。Windows 3.0の発売は、IBM PC/ATの発売から6年後の1990年であった。 日本語版Windows 3.1以降NEC版Windows 3.1、およびWindows for Workgroups 3.11以降Windows for Workgroups Version Historyは80286には対応していない。

OS/2 1.x DOS後継のプロテクトモード用オペレーティングシステムとしてIBMとマイクロソフトが共同開発したが、パソコン用OSのひとつとしての地位を獲得するにとどまった。OS/2 1.0の発売は、IBM PC/ATの発売から3年後の1987年であったOS/2の歩みを振り返る。 OS/2 2.0以降は80286には対応していない。

XENIX マイクロソフトによって開発されたUNIXである。

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

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

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

IBM PC/ATProtected Mode Basics by Robert Collinsトランジスタ技術 SPECIAL 特集 IBM PC & 80286のすべて 80286を搭載したIBM PC/ATではキーボードコントローラのI/Oにリセット機能が搭載されていた。これはI/Oポート64hにあり、通例はFEhを書き込みそのbit0を0にすることでリセット動作となる。これに先立ち当該プログラムはリセット後に処理を再開するアドレスCS:IPをBIOS Data Areaの0040:0067hに保存する。それ以外のスタックの位置(SS:SP)などプログラムの動作継続に必要な情報は当該プログラム自身のデータ領域などに保存する。次にリセット後の動作を決めるシャットダウンコードをRTC用 不揮発性CMOSメモリのオフセット0FhにI/Oポート70h, 71hを使用して書き込む。5を書き込めばリアルモードへの復帰、0を書き込めば通常の電源ON、またはリセットスイッチ押下である。プロテクトモードから戻るとBIOSはBIOS Data Areaに保存したアドレスから当該プログラムの実行を再開させる。当該プログラムはあらかじめ保存しておいたスタックの位置などの情報を戻す。

NEC PC-9800シリーズ PC-9800シリーズでは1986年に登場したPC-9801VXPC-9801VXに80286とV30の両方が搭載され、このとき80286とV30を切り替えるためのリセット用I/Oポートが設けられている。該当機ではI/O 00F0hに0を出力することでCPUがV30に切り替わらずにリセットされるが、これに先立ちリセット後に処理を続行するか再起動するかを事前に設定しておく必要がある。この設定はI/O 0035hのbit5,7にあり、再起動の場合は両方のbitを1に、処理続行の場合はbit7を0に設定する通常この操作はI/O 0037hのコントロールポートを介して行う。I/O 0037hに0Ahを書き込めばI/O 0035hのbit5が0に、0Bhを書き込めば1になる。同様に0Eh・0Fhを書き込めばI/O 0035hのbit7がそれぞれ0・1に設定される。。処理を続行する場合は事前に戻りアドレスとなるCS:IPをスタックに保存(PUSH)したうえで、そのスタックの位置(SS:SP)をメモリアドレス0000:0404から0407までの4バイトに保存しておく必要がある。

HMAの活用 上記の通り80286はリアルモードとプロテクトモードを備えており、起動直後や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ビットをゼロにするために外部ハードウェアを使用すべきである」としている原文:If any real-mode program relies on address space wrap-around (e.g. FFF0:0400 = 0000:0300), then external hardware should be used to force the upper 4 addresses to zero during real mode. 。

アドレス線を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#というピンを追加したIntel 64 and IA-32 Architectures Software Developer Manuals。これは外部ハードウェアでA20を無効にしても80486がキャッシュに保存されたHMAにアクセスしてしまうためである。このA20M#を制御するのは、PC/ATではキーボードコントローラで変化していない。

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

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

PUSHF/POPF命令で読み書きできる16ビット分のフラグのうち、上位4ビットは8086世代(V30V30ではbit15が「エミュレーションモード・フラグ」に割り当てられており、8080エミュレーション機能に関係する。ただしx86として動作している限りは8086/80186互換の挙動になり、bit15は1を返す。、80186などを含む)では使われていない予約ビットとなっていた。実際はその部分が1111bとして読み出せたものの、変更はできなかった。80286ではこの部分がプロテクトモードで使われるようになったため、リアルモードではゼロクリアされた状態になった。さらに仮想86モードを持つ80386からはリアルモードにおいてもこのビットが変更可能な仕様になっている。すなわちリアルモードの時点 (BIOSや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ではこれらの命令を特権命令にする機能を持つとしている。

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

廃止された命令 80286ではPOP CS命令(オペコード 0F)は廃止された。80186/V30も同様である。このオペコードは、80286以降、拡張命令のプリフィックスとして使用された。80286で使われている0Fプリフィックスは、上記のシステム命令のうち、ARPL以外の15命令が該当する特に80386以降では、条件ジャンプでnearジャンプ(-32768から+32767までの相対アドレス指定)を行うときのプリフィックスにも使われるようになった。80286およびそれ以前の条件ジャンプ命令はshortジャンプ(-128から+127までの相対アドレス指定)しか使えない。。

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

既存命令の仕様変更 80286はリアルモードにおいて8086や80186と高い互換性を持つものの、完全に等価というわけではない。異なる点としては、80286以降ではPUSH SP命令の挙動が変更されている8086のPUSH SP命令でスタックポインタSPを退避させる場合、SPから2が減算された後のSP値が記録される。例えば、PUSH SPのあとPOP AXを実行するとAXにはSP-2がロードされる。80286以降ではPUSH SPの際に減算される前の元のSP値を退避するようになった。この挙動の違いはプログラムが8086で実行されているのか、80286で実行されているのかを判別することに使用できる。。また既存命令の組み合わせであっても、プロテクトモード上では挙動の異なる場合がある80286ではフラグレジスタの使われていなかった予約ビットのいくつかに新たな意味を持たせており、その値によって一部の既存命令の挙動に影響が出る。例えば既存のPOPF命令はプロテクトモードにおいてIO特権レベルを示すIOPLフラグが変更できるようになっており、これによって既存の命令のうち特権レベルに依存するようになった命令(I/Oや、割り込みフラグの制御命令)が影響を受ける。また他のタスクから呼び出されたプログラムではそのためのNTフラグが立っており、IRETの動作に影響する。。

このほか変更点として、シフト・ローテイト命令で指定できる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を想定した新たなフラグが追加されている。 IOPL (IO privilege level) フラグ bit12・13を用いる2ビット分のフラグで、0から3までのフラグ状態を持ち、いわゆるIO特権レベルを表す。通常はPOPF命令でなければ変更できない。 NT (Nested task) フラグ bit14。裏のタスクが有効であることを示すフラグ。割り込みなどで呼び出された場合に1となり、これによりIRET命令でのリターン処理の動作が変わる。

なおbit15は予約ビットになっている。

MSW 80286ではMSW (Machine status word) レジスタが追加された。MSWを読み書きするLMSW、SMSWという専用の命令が用意されている。MSWは16bit分あるが、80286で定義されているのは下位4ビット分だけである。80386以降では新たに設けられたコントロールレジスタに統合され、CR0レジスタの下位16ビットが該当するが、互換性のためMSWとしてもアクセスできる。 PE (Protection enable) MSWのbit0。プロテクトモードであることを表す。このbitをセットすることでプロテクトモードになる。 MP (Math present) MSWのbit1。FPUが存在する場合にセットされる。 EM (Emulate math coprocessor) MSWのbit2。このビットがセットされているとFPUが無い扱いになる。 TS (Task switched) MSWのbit3。タスク切り替え時にセットされる。

割り込み 8086では割り込みは、割り込み4まで定義されており、80286では割り込み5以降が追加された。割り込み5から31まではインテル予約済みであったが、IBM PCでは割り込み8から15までを8259A経由の外部割込みに割り当てていた。プロテクトモードのOS/2などは8259Aの割り込み番号を別の値に変更するInt 50 - IRQ0 relocated by OS/2 v1.x。 割り込み0:除算エラー 除算命令(DIV, IDIV)で0で割ろうとした場合や商が大きすぎてレジスタに収まらない場合に発生する。 割り込み1:シングルステップ割り込み 割り込み2:NMI(マスク不可能割り込み) 割り込み3:ブレークポイント割り込み 割り込み4:INTOオーバーフロー 割り込み5:バウンドチェック BOUND命令に指定されたオペランドが、配列の範囲外に出ていると発生する。 割り込み6:無効オペコード 割り込み7:コプロセッサ不在 タスクスイッチ後、または、80287が装着されていないときに80287の命令を実行すると発生する。 割り込み8:ダブルフォルト 例外を処理しているときにさらに別の例外が発生し処理できなくなったときに発生する。 割り込み9:コプロセッサ・セグメント・オーバーラン 割り込み10:無効タスク・ステート・セグメント 割り込み11:セグメント不在 メモリ上に無いスワップアウトされたセグメントにアクセスした場合に発生する。この割り込みは80286のプロテクトモードで仮想記憶のために使用される。 割り込み12:スタック・フォルト 割り込み13:一般保護例外 80286のリアルモードでは、オフセットFFFFにあるワードオペランドをアクセスしたり、オフセットFFFFから複数バイトの命令を実行しようとすると発生する。8086ではオフセット0にラップアラウンドし例外は発生しない。80286のプロテクトモードでは、データセグメント内の命令の実行、コードセグメント内のデータの書き替え、現在の特権レベルより高い特権レベルのセグメントへのアクセスなどでも一般保護例外が発生する。 割り込み14 - 15:インテル予約済み 割り込み16:コプロセッサ・エラー IBM PC/ATでは80287のERROR#ピンを80286に直結せず、割り込みコントローラ8259Aに接続する設計とした。コプロセッサ(FPU)を内蔵した80486以降のCPUではIBM PC/ATとの互換性を維持するためにCPUにFERR#, IGNNE#というピンを追加したが、CR0レジスタのNEビットを1にすると8259A経由ではなく本来の割り込み16でコプロセッサのエラーを通知する。 割り込み17 - 31:インテル予約済み

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

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

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

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

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

周辺LSI 80287 NPX 80286用の数値演算コプロセッサ。8086用のコプロセッサである8087と異なりI/Oポート (00F8H - 00FDH) を用いてデータや命令のやり取りを行う。パッケージは40ピンDIPである。 82284 クロック生成器 82288 バスコントローラ 82289 バス調停器 8259A 割り込みコントローラ

CPUアクセラレータ