パスワードを忘れた? アカウント作成

8086マイクロコードの読み方」記事へのコメント

  • by Anonymous Coward on 2021年10月15日 1時11分 (#4132525)

    また同時にキャリーフラグの検査を行う。キャリーフラグは3つめの命令(CR=2)のときに格納したflagsで立つことがある。ざっくり条件を書くと、6を足した(AAAの場合)計算結果が9を超えた場合である。

    この理解は間違いです。キャリーが立つのは入力の下位ニブルが9より大きい時です。計算結果ではありません。インテルのマニュアルからだと

    IF ((AL AND 0FH) > 9) OR (AF ← 1)
    THEN
            AL ← AL + 6;
            AH ← AH + 1;
            AF ← 1;
            CF ← 1;
    ELSE
            AF ← 0;
            CF ← 0;
    FI;
    AL ← AL AND 0FH;

    キャリーを設定するのはCR=0の命令です。

    特許のページからですが、まず、この文書のAレジスタはAL、Xレジスタ82はAHに相当するようです。Xレジスタ82とXレジスタ108は全くの別物です。

    There are six types of microcode instructions in the present invention. Type 1 is an ALU conditioning instruction which sets up ALU 134, which is taken to include PSW 136, to perform a specified function. A type 0 microcode instruction is a short jump which provides for a conditional jump within the microcode burst or sequence. A type 4 instruction is a bookkeeping instruction. Other types include a type 6 memory cycle, type 5 jump cycle and type 6 long jump cycle with an address save.

    AAA/AASの例に出てくるのはタイプ0,1,4だけです。

    In the case of the ASCII addition adjust and subtract adjust, as shown in TABLE 7, the microcode burst consists of 8 microcode instructions. The first microcode instruction, moves the contents of A to the lower 8 bits of the 16 bit temporary register TMP A 138.


    0 A tmpaL 1 XI tmpa

    Aレジスタの内容をTMP Aレジスタの下位8ビットに転送します。

    The second half of the microcode instruction is an ALU conditioning command which preconditions ALU 134 to add without carry the contents of TMP A 138 and TMP B 142. The opcode symbolically represented by XI consists of bits 13 through 17, which five bits are loaded in opcode register 110 and decoded through ROM 132 to ALU 134.

    0番地の命令はTMP AとTMP Bレジスタのキャリーなし加算をALUにセットアップします。データが揃っていないので、設定するだけです。

    Bit 21 is a flag bit which indicates whether or not the PSW flags are to be updated. The ALU is preconditioned to test the contents of temporary register A to determine whether or not they exceed 9 or whether the auxiliary carry flag is set.

    TMP Aレジスタの下位4ビットを9と比較し、キャリーフラグをセットします。bit3 and (bit2 or bit1)ですみます。

    The precharged ALU bus 16 is set at the beginning of each clock cycle to a full complement of ones and is selectively pulled down by microcode instruction 1, by enabling appropriate pull down circuitry 160 diagrammatically shown in FIG. 2 to discharge selected lines of ALU bus 16 and to load a binary 6 into TMP B 142.


    1 ONES tmpb

    定数6をTMP Bレジスタに転送します。加算はキャリーがあって大変なのでALUを使います。

    A conventional comparator circuit 162 tests the contents of temporary register A to determine whether or not the contents is greater than 9. If so the output of comparator 162 is true and combined in OR gate 164 with the AUX-CARRY bit from PSW 136. The output of OR gate 164 enables adder 166 which then adds the contents of TMP A 138 and TMP B 142. The circuitry of FIG. 2 or its equivalent is included within ALU 134 and is enabled by the corresponding ALU opcode.

    比較器の出力にしたがってALUの動作を決めます。つまり下位ニブルが9より大きいか、補助キャリーが立っていれば6を足し(AASなら引き)ます。いずれの場合でも上位ニブルは0にします。PDFの終わりについてあるfig.2に、ADDERとTMP Bレジスタの間に[+/-]という箱がありますが、これで加算と減算を切り替えます。その下に0FhとANDして上位ニブルをクリアする回路も描いてあります。この演算ではキャリーは変化しません。

    Microcode instruction 2 takes the contents of the sum from ALU 134 and reloads the sum into accumulator 90. ALU 134 is then preconditioned by the second half of microcode instruction 2 to decrement the contents of TMP B.


    2 Σ A 1 DEC tmpb F

    ΣはALUの出力で、Aレジスタに転送します。またDEC tmpbでTMP Bレジスタの内容をデクリメントするよう設定します。設定だけで演算はしません。Fは不明です。

    The least significant bit of X register 108, X0, is then tested in microcode instruction 3, namely bit 3 of the instruction address. If true, the microcode instruction will follow a short jump to microcode instruction 5 wherein the contents of X register 82 will be loaded into register TMP B 142. ALU 134 having been preconditioned by microcode instruction 2, will decrement the contents of TEMP B 142.

    X register 108 loads bits 3-6 of the byte and assumes that the opcode of the instruction is an ALU opcode. The entire byte is loaded into AR register 112.

    Xレジスタ108とXレジスタ82は全くの別物です。ここでテストしているのはオペコードの3ビット目で、AAAなら0、AASなら1です。


    3 0 X0 5

    Xレジスタ108の最下位ビット=オペコードの3ビット目をテストします。1なら

    4 1 INC tmpb

    をスキップします。つまりAAAならインクリメント、AASならデクリメントが設定されます。

    The second half of microcode instruction 5 will then cause a short jump to the end of the microcode instruction if the inverse of the carry flag is true indicating no carry, NCY, otherwise microcode instruction 6 will be executed wherein the sum will be placed in X register 82. In either case, the bookkeeping instruction will generate a ROM control signal, RNI, from circuit 144 to run the next instruction, i.e. indicate to loader 130 to run the next machine language instruction.


    5 X tmpb 0 NCY 7
    6 Σ X 4 none RNI
    7 4 none RNI

    このXはXレジスタ82です。AAA/AASに応じてインクリメント/デクリメントを設定してあるので、Xレジスタ82の内容をTMP Bに転送すると、Σに結果が現れます。キャリーフラグに応じてXレジスタ82に書き戻すかどうかを決めます。

    If, however, an ASCII add instruction is indicated, microcode instruction 3 will be omitted and ALU 134 preconditioned to increment contents of TMP B. Again, microcode instruction 5 will insert the contents of temporary register 82 into TMP B with the result that the incremented contents of X register 82 may be loaded into X register 82 as required and an ASCII multiplication division.

    AAAの場合はインクリメントすると書いてあります。

    https://www.pcjs.org/documents/manuals/intel/8086/ops/AAA/ [pcjs.org]

    The 8086 and 8088 implement AAA differently than later processors. On the 80286 and later processors, the first addition is performed on AX instead of AL, incrementing the AH register if a carry is generated out of AL. If AX contains OOFFh, executing AAA on an 8088 will leave AX=0105h. On an 80386, the same operation will leave AX=0205h. Despite the different implementation, this instruction does operate as intended for all valid operands.

    ALへ+6するのとAHに+1するのは別々の操作のようです。

    ここに返信
    • ご指摘ありがとうございます。
      キャリーの件は私の間違いです。
      続きをすぐに読みたかったのですが、仕事ですぐに読めませんので、
      後でにじっくり読ませていただきます。

    • by Anonymous Coward

      AAAとAASの+6と-6の切り替えはワイヤ一本でインプリシットにできるのに、インクリメントとデクリメントはマイクロコードで切り替えているのは不思議かもしれません。しかしAH←AH+1をマイクロコードで書くと

      0 X tmpa 1 ADD tmpa
      1 1 tmpb
      2 Σ X

      どのみち3命令必要な上、定数「1」の発生回路が余分に必要になります。定数はセレクタが爆発するので普通は定数ROMに格納されますが、それでも結構なリソース喰いです。

      一般に、A-B-CY = A+~B+!CYです。BとCYを反転させるだけで加算回路で減算できます。ビットの反転はOP=SUB信号とBの各データビットやCYをXO

      • > これで比較的ローコストに、少なくともセレクタを使うよりずっと簡潔にADD/SUBとINC/DECが統合されました。

        これを読んだときに気がついたのですが、特定(クロック速度の短い)のx86命令の各命令と先頭5ビットを並べると

        INC Register 01000
        DEC Register 01001

        ADC Reg/Memory and register to ether 00010
        SBB Reg/Memory and register to ether 00011

        ADD Reg/Memory and register to ether 00000
        SUB Reg/Memory and register to ether 00101

        このようになり、ADD/SUBはちょっと違いますが、前から(0から数えて)0ビット目から3ビット目までは共通で、4ビット目だけが異なっており、このビットで+-の操作を決めているように見えます。
        ALUへの操作命令は5ビット長で、一部の命令は直接ALUへ入力されているようですので、(その場合はマイクロコードでALU操作はせずにもう一方のALUへの入力だけをしているっぽい)

        これらのビット列が命令取り込み時に直接ALUへ入力されていると考えてみると、
        > ADD/SUBとINC/DECが統合
        というのは確かにそのとおりなのでしょう。

        もう少し考えると、とのビットがどういう操作に対応しているかわかるかもしれないです。

      • by Anonymous Coward

        > データ計算はBの全ビットにOP=SUBをxorすれば望みのものが得られます。ボロ―計算はBの全ビットにOP=SUB or OP=DECをxorしたものを使えばよいです。

        OP=SUBとOP=DECは決して両立しないので、orはロジックは不要で、加減算計算用B'=B xor (OP=SUB)*16とすると、キャリー・ボロ―計算用はB''=B' xor (OP=DEC)*16ですみます。

        > Aの全ビットにOP=ADD or OP=SUBをandすれば、容易に0を手に入れられます。

        オペランドが一つしかなく、相手が0である命令にNEGやNOTがありますが、こういった情報はマイクロコードから供給され、orのようなロジックは不要でし

    • by Anonymous Coward

      こういう記述がありました。

      The opcode will either be a unique ASCII adjustment for addition or subtraction to be performed upon the contents of the microcode b field, which field includes bits 18 through 20 in the case of an ALU instruction. Bit 21 is a flag bit which indicates whether or not the PSW flags are to be updated.

      Typは3ビット、aは4ビット、bは3ビット、Fは1ビットのようです。


      2 Σ A 1 DEC tmpb F

      TMP Aの下位ニブルと9との比較の結果をPSWに転送するのがこのサイクルのようです。命令によってアップデートされるフラグはばらばらですが、それはaフィールド(オペコード)が内包するようです。AAA/AASではCFとAFだけがアップデートされますが、それはオペコード(XI)からテーブルでも引いているのでしょう。

開いた括弧は必ず閉じる -- あるプログラマー

処理中...