8086命令セット

8086の命令セットについて調べたことをまとめました。なお、基本的なエンコーディングについては記しませんので適当な資料を参照してください。

# 参考資料

* [1] PC-9801マシン語ゲームグラフィックス, 日高 徹 (著), 青山 学 (著), 小学館, 1991<br>![20160814-98game.jpeg](https://qiita-image-store.s3.amazonaws.com/0/103733/88553800-0c33-1070-0a64-a4558be3798f.jpeg)
* [2] 8086ファミリ・ハンドブック, 相沢 一石 (著), CQ出版社, 1989<br>![a.jpeg](https://qiita-image-store.s3.amazonaws.com/0/103733/014aa6bb-4639-11ab-4364-944fc220b7c2.jpeg)
* [3] 80x86/80x87ファミリー・テクニカルハンドブック, Robert L. Hummel (著), 槌田 浩一 (訳), 技術評論社, 1993<br>![a.jpeg](https://qiita-image-store.s3.amazonaws.com/0/103733/95f48087-2e39-c438-c963-b383994e76ea.jpeg)

* [4] PC-9800シリーズ ザ・プロテクトII プログラム解読法入門, 井上 智博 (著), 技術開発室 (著), 秀和システムトレーディング, 1987<br>![a.jpeg](https://qiita-image-store.s3.amazonaws.com/0/103733/1f2e2737-4f14-a5d8-bb79-7ee1c87b2d53.jpeg)

* [5] Undocumented 8086 Opcodes, OS/2 Museum, http://www.os2museum.com/wp/undocumented-8086-opcodes/
* [6] The Intel 8086 / 8088/ 80186 / 80286 / 80386 / 80486 Instruction Set, http://zsmith.co/intel.html
* [7] Undocumented 8086 Opcodes, Part I | OS/2 Museum, http://www.os2museum.com/wp/undocumented-8086-opcodes-part-i/

# オペコードマップ

|   | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 0 |ADD<br>EB,GB|ADD<br>EW,GW|ADD<br>GB,EB|ADD<br>GW,EW|ADD<br>AL,IB|ADD<br>AX,IW|PUSH<br>SEG|POP<br>SEG|OR<br>EB,GB|OR<br>EW,GW|OR<br>GB,EB|OR<br>GW,EW|OR<br>AL,IB|OR<br>AX,IW|PUSH<br>SEG|POP<br>SEG|
| 1 |ADC<br>EB,GB|ADC<br>EW,GW|ADC<br>GB,EB|ADC<br>GW,EW|ADC<br>AL,IB|ADC<br>AX,IW|PUSH<br>SEG|POP<br>SEG|SBB<br>EB,GB|SBB<br>EW,GW|SBB<br>GB,EB|SBB<br>GW,EW|SBB<br>AL,IB|SBB<br>AX,IW|PUSH<br>SEG|POP<br>SEG|
| 2 |AND<br>EB,GB|AND<br>EW,GW|AND<br>GB,EB|AND<br>GW,EW|AND<br>AL,IB|AND<br>AX,IW|ES:|DAA|SUB<br>EB,GB|SUB<br>EW,GW|SUB<br>GB,EB|SUB<br>GW,EW|SUB<br>AL,IB|SUB<br>AX,IW|CS:|DAS|
| 3 |XOR<br>EB,GB|XOR<br>EW,GW|XOR<br>GB,EB|XOR<br>GW,EW|XOR<br>AL,IB|XOR<br>AX,IW|SS:|AAA|CMP<br>EB,GB|CMP<br>EW,GW|CMP<br>GB,EB|CMP<br>GW,EW|CMP<br>AL,IB|CMP<br>AX,IW|DS:|AAS|
| 4 |INC<br>RW|INC<br>RW|INC<br>RW|INC<br>RW|INC<br>RW|INC<br>RW|INC<br>RW|INC<br>RW|DEC<br>RW|DEC<br>RW|DEC<br>RW|DEC<br>RW|DEC<br>RW|DEC<br>RW|DEC<br>RW|DEC<br>RW|
| 5 |PUSH<br>RW|PUSH<br>RW|PUSH<br>RW|PUSH<br>RW|PUSH<br>RW|PUSH<br>RW|PUSH<br>RW|PUSH<br>RW|POP<br>RW|POP<br>RW|POP<br>RW|POP<br>RW|POP<br>RW|POP<br>RW|POP<br>RW|POP<br>RW|
| 6 |JO*<br>SHORT|JNO*<br>SHORT|JB*<br>SHORT|JNB*<br>SHORT|JZ*<br>SHORT|JNZ*<br>SHORT|JBE*<br>SHORT|JNBE*<br>SHORT|JS*<br>SHORT|JNS*<br>SHORT|JP*<br>SHORT|JNP*<br>SHORT|JL*<br>SHORT|JNL*<br>SHORT|JLE*<br>SHORT|JNLE*<br>SHORT|
| 7 |JO<br>SHORT|JNO<br>SHORT|JB<br>SHORT|JNB<br>SHORT|JZ<br>SHORT|JNZ<br>SHORT|JBE<br>SHORT|JNBE<br>SHORT|JS<br>SHORT|JNS<br>SHORT|JP<br>SHORT|JNP<br>SHORT|JL<br>SHORT|JNL<br>SHORT|JLE<br>SHORT|JNLE<br>SHORT|
| 8 |GRP1B|GRP1W|GRP1B|GRP1WB|TEST<br>EB,GB|TEST<br>EW,GW|XCHG<br>EB,GB|XCHG<br>EW,GW|MOV<br>EB,GB|MOV<br>EW,GW|MOV<br>GB,EB|MOV<br>GW,EW|MOV<br>EW,SW|LEA<br>GW,M|MOV<br>SW,EW|POP<br>EW|
| 9 |NOP|XCHG<br>RW,AX|XCHG<br>RW,AX|XCHG<br>RW,AX|XCHG<br>RW,AX|XCHG<br>RW,AX|XCHG<br>RW,AX|XCHG<br>RW,AX|CBW|CWD|CALL<br>FAR|WAIT|PUSHF|POPF|SAHF|LAHF|
| A |MOV<br>AL,OB|MOV<br>AX,OW|MOV<br>OB,AL|MOV<br>OW,AX|MOVSB|MOVSW|CMPSB|CMPSW|TEST<br>AL,IB|TEST<br>AX,IW|STOSB|STOSW|LODSB|LODSW|SCASB|SCASW|
| B |MOV<br>RB,IB|MOV<br>RB,IB|MOV<br>RB,IB|MOV<br>RB,IB|MOV<br>RB,IB|MOV<br>RB,IB|MOV<br>RB,IB|MOV<br>RB,IB|MOV<br>RW,IW|MOV<br>RW,IW|MOV<br>RW,IW|MOV<br>RW,IW|MOV<br>RW,IW|MOV<br>RW,IW|MOV<br>RW,IW|MOV<br>RW,IW|
| C |RET*<br>IW|RET*|RET<br>IW|RET|LES<br>GW,EP|LDS<br>GW,EP|MOV<br>EB,IB|MOV<br>EW,IW|RETF*<br>IW|RETF*|RETF<br>IW|RETF|INT3|INT<br>IB|INTO|IRET|
| D |GRP2<br>EB,1|GRP2<br>EW,1|GRP2<br>EB,CL|GRP2<br>EW,CL|AAM<br>IB|AAD<br>IB|SALC*|XLAT|ESC<br>EW|ESC<br>EW|ESC<br>EW|ESC<br>EW|ESC<br>EW|ESC<br>EW|ESC<br>EW|ESC<br>EW|
| E |LOOPNE<br>SHORT|LOOPE<br>SHORT|LOOP<br>SHORT|JCXZ<br>SHORT|IN<br>AL,IB|IN<br>AX,IB|OUT<br>IB,AL|OUT<br>IB,AX|CALL<br>NEAR|JMP<br>NEAR|JMP<br>FAR|JMP<br>SHORT|IN<br>AL,DX|IN<br>AX,DX|OUT<br>DX,AL|OUT<br>DX,AX|
| F |LOCK|LOCK*|REPNE|REPE|HLT|CMC|GRP3B|GRP3W|CLC|STC|CLI|STI|CLD|STD|GRP4|GRP5|

- 縦: オペコードの上4bit (hex)
- 横: オペコードの下4bit (hex)
- 上段: ニーモニック
 - *: Undocumented - [5][7]参照
      - ただしD6hのSETALCについては[3]に80286以降とあり、[4]102ページにはD6hがXLATと同じとの記載あり。[7]ではSALC(SETALC)との記載あり。80C88での検証の結果[7]が正解。
      - F1hについては[3]642ページのオペコード・マップにLOCKとの記載あり。
      - GRP2, GRP3B, GRP3Wについては[3]646ページに記載あり。80C88での検証の結果、GRP2は現行プロセッサとは異なり[7]のSETMO/SETMOCが正解。ここでは(SMO)としてある。
      - GRP5のPUSHついては80C88での検証による。
      - GRP4についてはGRP5と同様の命令がバイトアクセスで実行される。いずれもスタックに積むときSPは通常通り2ずつ引かれるが、メモリーへの書き込みが下位8ビットのみとなる。また、メモリー読み取りも1バイトで行われ上位8ビットはFFhとなる。
      - POP CSおよびMOV CSによるCSの変更については、プリフェッチキューがフラッシュされない。
      - LEAにレジスターオペランドを指定すると、内部に残っている最新のEAが現れる。PUSH, POP等でも変化する。
      - LES/LDSにレジスターオペランドを指定すると、内部に残っている最新のメモリーアクセスの内容が現れる。バイトアクセスの場合上位8ビットは書き込み時符号拡張、読み取り時FFhとなる。
      - CALL FAR/JMP FARにレジスターオペランドを指定すると、ALUの入力側に残っている値がIPに、残っているEAの+2の内容が読み取られCSにセットされる。バイトオペランドの場合でもIPは16ビット反映され、CSは上位8ビットがFFhになる。
 - GRPで始まる項目: Mod-Reg-R/MバイトのRegフィールドにより命令が異なる。別表参照。オペランドはGRP2のみ上の表で確定、それ以外は別表で確定。
- 下段: オペランド
    - 2文字表現
        - B: 1バイト
        - W: 1ワード
        - P: 1ダブルワード
        - I: Immediate
        - O: メモリー (Displacementによる指定)
        - E: メモリーまたはレジスター (Mod-Reg-R/MバイトのMod-R/Mフィールドによる指定)
        - G: レジスター (Mod-Reg-R/MバイトのRegフィールドによる指定)
        - R: レジスター (オペコードの下位3ビットによる指定)
        - S: セグメントレジスター (Mod-Reg-R/MバイトのRegフィールドによる指定)
        - CL: レジスターCL
        - AL: レジスターAL
        - AX: レジスターAX
        - DX: レジスターDX
    - 1: 1
 - FAR: セグメントアドレスとオフセットアドレス (32bit) によるセグメント外ジャンプ・コール先の表現
 - NEAR: 次の命令からの相対アドレス (符号付き16bit) によるセグメント内ジャンプ・コール先の表現
 - SHORT: 次の命令からの相対アドレス (符号付き8bit) によるセグメント内ジャンプ・コール先の表現
 - SEG: セグメントレジスター (オペコードのbit4-3による指定)
 - M: メモリー (Mod-Reg-R/MバイトのMod-R/Mフィールドによる指定)

|   | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|GRP1B|ADD<br>EB,IB|OR<br>EB,IB|ADC<br>EB,IB|SBB<br>EB,IB|AND<br>EB,IB|SUB<br>EB,IB|XOR<br>EB,IB|CMP<br>EB,IB|
|GRP1W|ADD<br>EW,IW|OR<br>EW,IW|ADC<br>EW,IW|SBB<br>EW,IW|AND<br>EW,IW|SUB<br>EW,IW|XOR<br>EW,IW|CMP<br>EW,IW|
|GRP1WB|ADD<br>EW,IB|OR<br>EW,IB|ADC<br>EW,IB|SBB<br>EW,IB|AND<br>EW,IB|SUB<br>EW,IB|XOR<br>EW,IB|CMP<br>EW,IB|
|GRP2|ROL|ROR|RCL|RCR|SHL|SHR|(SMO)*|SAR|
|GRP3B|TEST<br>EB,IB|TEST*<br>EB,IB|NOT<br>EB|NEG<br>EB|MUL<br>EB|IMUL<br>EB|DIV<br>EB|IDIV<br>EB|
|GRP3W|TEST<br>EW,IW|TEST*<br>EW,IW|NOT<br>EW|NEG<br>EW|MUL<br>EW|IMUL<br>EW|DIV<br>EW|IDIV<br>EW|
|GRP4|INC<br>EB|DEC<br>EB|(BCALL)<br>EW*|(BCALL)<br>EP*|(BJMP)<br>EW*|(BJMP)<br>EP*|(BPUSH)<br>EW*|(BPUSH)<br>EW*|
|GRP5|INC<br>EW|DEC<br>EW|CALL<br>EW|CALL<br>EP|JMP<br>EW|JMP<br>EP|PUSH<br>EW|PUSH<br>EW*|

# 命令クロックサイクル

## Effective Address (EA)

クロックサイクル計算によく出てくる+EAの計算方法

* Displacement (disp): 6
* BX, SI, DI: 5
* BX+disp, BP+disp, SI+disp, DI+disp: 9
* BX+SI, BP+DI: 7
* BX+DI, BP+SI: 8
* BX+SI+disp, BP+DI+disp: 11
* BX+DI+disp, BP+SI+disp: 12

上は[2], [3], [6]に同様の記載あり。[1]では7 or 8, 11 or 12という表記で一部まとめられているが同じと見て良さそう。

[1], [2], [3], [6]で、セグメントオーバーライドで2クロック加えるとある。また、[1], [2], [6]では奇数アドレスの16ビットアクセスで4クロック加えるとあるが、おそらくこれは正確ではない。

[3], [6]は外部バス8ビットの8088における16ビットアクセス時のクロックサイクルを別表記しており、8086における奇数アドレスの16ビットアクセスもそれに準ずる形が正しいと考えられる。大雑把にはメモリーアクセス1回につき4クロック、2回で8クロックの差があるが、+EAに限らない。(+EAはMod-Reg-R/Mバイトを持つ命令にのみ使われるが、奇数アドレスにおける遅延は、displacement指定のMOVや、スタックポインターを奇数にした時のPUSH/POP等でも同様と考えられる。)

以下、8088の16ビットアクセスの場合のクロックサイクルに差がある場合、カッコ書きで記載する。16ビットのメモリーアクセスを行わない命令には適用されない。

## I/Oを伴わない1バイト命令

* DAA, DAS: 4
* AAA, AAS: 8 - [1], [2]では4、[3], [6]では8とされているが、80C88での検証の結果8が正解
* INC RW, DEC RW: 2 - [1], [2]では2、[3], [6]では3とされているが、単純な演算命令かつ1バイトの命令が、2バイトで表現した同じ命令と実行時間が変わらないとは考えにくいため、2が正しいと推測
* NOP, XCHG RW,AX: 3
* CBW: 2
* CWD: 5
* SAHF, LAHF: 4
* HLT, CMC, CLC, STC, CLI, STI, CLD, STD: 2
* WAIT: 3+5N - [1], [2]では3+5N、[3]では3、[6]では4とされている

## ストリング命令

REPはREPE並びにREPNEプリフィックスのいずれでも良い。

* MOVSB, MOVSW: 18 (26)
* REP MOVSB, REP MOVSW: 9+17N (9+25N)
* CMPSB, CMPSW: 22 (30)
* REP CMPSB, REP CMPSW: 9+22N (9+30N)
* STOSB, STOSW: 11 (15)
* REP STOSB, REP STOSW: 9+10N (9+14N)
* LODSB, LODSW: 12 (16)
* REP LODSB, REP LODSW: 9+13N (9+17N) - [1]だけが本命令のクロック数を表示しており、カッコ内は推測
* SCASB, SCASW: 15 (19)
* REP SCASB, REP SCASW: 9+15N (9+19N)

## Mod-Reg-R/Mバイトを伴わない命令

* PUSH SEG: 10 (14)
* POP SEG: 8 (12)
* PUSH RW: 11 (15)
* POP RW: 8 (12)
* PUSHF: 10 (14)
* POPF: 8 (12)
* MOV AL,OB, MOV OB,AL, MOV AX,OW, MOV OW,AX: 10 (14)
* MOV RB,IB, MOV RW,IW: 4
* RET IW: 12 (16) - [3], [6]では20 (24)
* RET: 8 (12) - [3], [6]では16 (20)
* RETF IW: 17 (25) - [3], [6]では25 (33)
* RETF: 18 (26) - [3], [6]では26 (34)
* INT3: 52 (72)
* INT IB: 51 (71)
* INTO: 4/53 (4/73) - ジャンプ時53 (73)
* IRET: 24 (36) - [3], [6]では32 (44)
* AAM IB: 83
* AAD IB: 60
* XLAT: 11
* Jcc (条件ジャンプ): 4/16 - ジャンプ時16
* LOOPNE: 5/19 - ジャンプ時19
* LOOPE: 6/18 - ジャンプ時18
* LOOP: 5/17 - ジャンプ時17
* JCXZ: 6/18 - ジャンプ時18
* CALL FAR: 28 (36)
* CALL NEAR: 19 (23)
* JMP NEAR, JMP FAR, JMP SHORT: 15
* IN AL,IB, IN AX,IB, OUT IB,AL, OUT IB,AX: 10 (14)
* IN AL,DX, IN AX,DX, OUT DX,AL, OUT DX,AX: 8 (12)
- オペランドがAL,IB, AX,IWとなるADD, OR, ADC, SBB, AND, SUB, XOR, CMP, TEST: 4

## Mod-Reg-R/Mバイトを伴う命令

数が多いので一部オペランドごとに分ける。レジスターとメモリーの両方が指定可能な場合は、/で区切ってレジスターの場合を左側、メモリーの場合を右側に示す。

- EB,GB, EW,GW
    - ADD, OR, ADC, SBB, AND, SUB, XOR: 3/16+EA (3/24+EA)
    - CMP, TEST: 3/9+EA (3/13+EA)
    - XCHG: 4/17+EA (4/25+EA)
    - MOV: 2/9+EA (2/13+EA)
- GB,EB, GW,EW
    - ADD, OR, ADC, SBB, AND, SUB, XOR, CMP: 3/9+EA (3/13+EA)
    - MOV: 2/8+EA (2/12+EA)
- MOV EW,SW: 2/9+EA (2/13+EA)
- MOV SW,EW: 2/8+EA (2/12+EA)
- LEA GW,M: ?/2+EA - レジスターオペランドは指定禁止のため不明
- LES GW,EP, LDS GW,EP: ?/16+EA (?/24+EA) - レジスターオペランドは指定禁止のため不明
- EB
    - NOT, NEG: 3/16+EA
    - MUL: 70/76+EA +演算時間0-7 - [3]ではメモリーオペランドについて(76+83)+EAとの表記があるがおそらく(76-83)+EAの記載ミス
    - IMUL: 80/86+EA +演算時間0-18
    - DIV: 80/86+EA +演算時間0-10
    - IDIV: 101/107+EA +演算時間0-11
    - INC, DEC: 3/15+EA
- EW
    - NOT, NEG: 3/16+EA (3/24+EA)
    - MUL: 118/124+EA (118/128+EA) +演算時間0-15 - [3]ではレジスターオペランドについて113-118との表記があるがおそらく記載ミス
    - IMUL: 128/134+EA (128/138+EA) +演算時間0-26
    - DIV: 144/150+EA (144/158+EA) +演算時間0-18 - [3]では8086のメモリーオペランドについて(154-172)+EAとされているが、[1], [2], [6]では(150-168)+EAであり、8088については[3], [6]ともに(158-176)+EA
    - IDIV: 165/171+EA (165/175+EA) +演算時間0-19
    - INC, DEC: 3/15+EA (3/23+EA)
- PUSH EW: 11/16+EA (15/24+EA) - レジスターオペランドについては、通常使われないため[1], [2], [6]では記載がない。
- POP EW: 8/17+EA (12/25+EA) - レジスターオペランドについては、通常使われないため[1], [2], [6]では記載がない。
- EB,IB, EW,IW
    - ADD, OR, ADC, SBB, AND, SUB, XOR: 4/17+EA (4/25+EA)
    - CMP: 4/10+EA (4/14+EA)
    - TEST: 5/11+EA
    - MOV: 4/10+EA (4/14+EA) - レジスターオペランドにおいて、通常使われないため[1], [6]では記載がなく、[2]では4、[3]では10とされている。MOVはメモリー転送を伴う場合に10なので、immediateでは4と推測
- GRP2 EB,1, GRP2 EW,1: 2/15+EA (2/23+EA)
- GRP2 EB,CL, GRP2 EW,CL: 8+4N/20+EA+4N (8+4N/28+EA+4N)
- ESC EW: 2/8+EA
- CALL EW: 16/21+EA (20/29+EA)
- CALL EP: ?/37+EA (?/53+EA) - レジスターオペランドは指定禁止のため不明
- JMP EW: 11/18+EA - [3]に8086と8088で同じクロックサイクルが示されているがそんなはずはない
- JMP EP: ?/24+EA - レジスターオペランドは指定禁止のため不明。[3]に8086と8088で同じクロックサイクルが示されているがそんなはずはない

## 掛け算命令の演算時間

掛け算は、ビットシフトと足し算により実現されていると考えられる。もっともシンプルな符号なし整数については、2進数で筆算の掛け算をするのと同じように、ビットシフトをしながら、ビットが1のところについて足し算をしていけば良い。

符号なし整数の掛け算 (MUL) については、8ビットの場合0-7、16ビットの場合0-15であるから、掛けられる数、または、掛ける数のうち、1のビットの数によって1サイクルずつ変わるものと考えられる。

符号付き整数の掛け算 (IMUL) については、8ビットの場合0-18、16ビットの場合0-26で、アルゴリズムを推測しにくい。符号なしに比べて、少なくとも+10サイクル余分にかかり、その幅も最大+11サイクル長くなっているから、符号判定、符号反転などをしているのかも知れない。

## 割り算命令の演算時間

割り算は、ビットシフトに引き算により実現されているものと思っている。2進数で筆算の割り算をするように、ビットシフトと引き算で実現することができる。

割り算命令は結果がレジスターに収まらない場合割り込みを生成するが、その場合に要するクロックサイクルは不明。

## バスサイクル

[2]21ページを参照。4ステートあり、最小4クロックサイクルを必要とする。最初のステートでアドレスが流れ、次のステートで書き込みではデータが流れ始める。さらにその次のステートの最後に、読み取りではデータ読み取りが行われるが、readyでない場合はこのステートが引き伸ばされる。最後のステートで後片付けみたいな感じになる。

上述のクロックサイクルはI/Oアクセスがすべて4サイクルで計算されているように見える。実際にはビデオRAMや遅いI/Oデバイスなどへのアクセスは4サイクルで完了せず、READY信号によるステートの引き伸ばしが行われる。

## EUとBIU

EU (Execution Unit) とBIU (Bus Interface Unit) は独立して動作しており、BIUは必要に応じて命令プリフェッチを行う。8086は6バイト、8088は4バイトのプリフェッチキューを持つ。バスがあいている間にプリフェッチすると良く言うが、実際にはEUが何サイクル後にI/Oを要求するか、BIUは知りようがないので、EUがI/Oを要求した時点でBIUは命令プリフェッチの最中だったということはありうると思う。そのような場合にも4ステートが完了してからEUのI/O要求が処理されるはず。

[2]16ページを参照。汎用レジスター8つはEU側にあり、セグメントレジスター4つとIPはBIU側にある。その他ALU、フラグレジスターとテンポラリーレジスターがEU側にあって、内部コミュニケーションレジスターがBIU側にあるらしい。

# その他特記事項

* 80286以降でMOV SS命令とその次の命令まで割り込み禁止されるが、8086/8088では任意のセグメントレジスターの変更に対して割り込み禁止となる。また、初期バージョンの8086/8088ではその機能が正しく実装されていないらしい。[3]414ページ
* 80C88で確認したところ、セグメントレジスターの変更に対する割り込み禁止は、連続していても適用される
* IDIV命令は最小値が-127 (8ビット) および-32767 (16ビット) だったらしい。80286以降は-128および-32768になっている。[3]240ページ他
* 80286以降はシフト・ローテート命令のカウントがマスクされる。有名。
* PUSH SPの挙動が80286以降と異なる。有名。PUSH SPしてPOP SPすると、何回POP SPを実行してもスタックポインターが戻らなかった記憶があるので、つまり、PUSHは引いた後の値をスタックに書くし、POPは足した後スタックから取り出した値で上書きしてしまう。
* フラグレジスター。8086ではビット12-15が必ず1。ビット1,3,5が必ず0。[3]57ページ、240ページ。ただし80C88および8088でビット1が1であることを確認している。
* フラグレジスター。8086では初期値がF000h。[3]233ページ。ビット1が1であればF002h。
* 8086には命令長の制限がない。[3]240ページ
* 8086の除算エラー例外発生時スタックに入るIPは除算命令の次の命令を指す。[3]241ページ
* NMIの特別扱い (IRETまで次のNMIを受け入れない) は80286以降。[3]241ページ
* 8086はリセット時FFFF:0000から開始、DS, ES, SSは0クリア。80286以降はF000:FFF0から開始。[3]233ページ、241ページ
* AAA命令の+6が80286以降はAXに対して行われる。[3]294ページ
* XCHG命令に対してLOCK信号が自動的にアサートされるのは80286以降。[3]519ページ
* REPプリフィックスのループ実行中に割り込みが発生した場合、スタックに入るIPがストリング命令の1バイト手前になるバグがある。8086/8088のみ、V20/V30では問題ない。割り込み許可状態で複数のプリフィックスを使用している場合に問題が発生しうる。[3]252ページ。80C88でも確認。シングルステップ実行で検証可能。
* WAIT命令についても、無意味なプリフィックスをつけていたとしても割り込み発生時はプリフィックスの後ろ側のIPがスタックに積まれる。80C88で確認。
* 80C88で確認したところ、IRET命令で割り込み許可にすると、すぐ次の命令を実行する前に割り込みが発生する。また、IRET命令でTFをセットすると、すぐ次の命令の実行後にシングルステップの割り込みが発生する。いずれもPOPF命令やSTI命令でセットした場合はすぐ次の命令では発生しない。これは現行プロセッサとは微妙に異なる。
* シングルステップ割り込みは優先度が低いが、命令実行前にTFがセットされていたら、命令や割り込み処理の結果TFがクリアされたとしても発生する。割り込みの場合割り込みハンドラーの最初の命令を実行する前に発生する。
* 80C88で確認したところ、WAIT命令やHLT命令の待ちの間にシングルステップ実行も割り込みとして扱われる。つまりPOPFでTFをセットした直後のWAIT/HLTはシングルステップ割り込みが発生しないため停止するが、その次以降のWAIT/HLTは停止しない。
* 80C88で確認したところ、REPプリフィックスによる繰り返しのシングルステップ実行では、CXが0になってももう一度REPプリフックス(IP-2)に戻る。これは現行プロセッサとは異なる。