あなたCPUなんか創ってどうするのかしら?! 第1章 第8節

~あんたCPUなんか創ってどうするのよ?! Vol.4~

2019/4/14
技術書典6
池袋サンシャインシティ 文化会館ビル2F 展示ホールD「う11」

第1章 第8節 減算命令とキャリーフラグ

表3に示すように、設計開始当初のTD4EX4の減算命令にはRAMの内容を減算する命令と、イミディエイトデータを減算する命令とがありました。しかし前節で述べたようにイミディエイトデータの減算命令は削除することに決めました。RAMへの書き込み命令を実現するには、それが最適だと判断したからです。

この節ではなぜ削除しても問題ないのかを説明します。

第1章 第8節 第1項 減算命令でのキャリーフラグの仕様

まずは前提。一般的なCPUでは、減算命令でのキャリーフラグの仕様が2種類あります。簡単に表にまとめると以下のようになります。

表4 減算命令のキャリーフラグの仕様
CPU 減算命令の実行後
結果が正の場合 結果が0の場合 結果が負の場合
6809, Z80, 8086等 0 0 1
6502, PIC, ARM等 1 1 0
TD4EX4 1 1 0

例えば5-2を計算すると答えは3ですが、キャリーフラグは6809やZ80や8086等では0になり、6502やPICやARM等では1になります。逆に2-5を計算した場合は6809やZ80や8086等では1に、6502やPICやARM等では0になります。これは設計思想の違いが結果に反映されているのであって、どちらが正しいとか誤っているとか言う訳ではありません。

TD4EX4のキャリーフラグは6502やPICやARM等と同じです。結果が正なら1に、負なら0になります。このような仕様に決めた理由は、もちろん使用するICの数を減らすためです。

TD4EX4では減算命令を2の補数との加算で処理しています。ICの数を減らすために、減算専用の回路を用意せず、加算用ICである74HC283を流用して減算を行っています。するとキャリーフラグは、答えが負の場合に1になり、正の場合には0になるのです。

この仕様は6809でアセンブラの基礎を学び、Z80で応用を学んだ筆者としては非常に使いにくいのですが、使用するICの数を減らすためには止むを得ないと判断しました。

第1章 第8節 第2項 イミディエイトデータの減算命令と加算命令

減算命令のキャリーフラグの仕様を前述のように決めた結果、TD4EX4ではイミディエイトデータによる減算命令の価値が下がりました。なぜならイミディエイトデータによる減算は、イミディエイトデータをあらかじめ2の補数化しておくことにより、加算に置き換えることができるからです。

数式1 イミディエイトデータによる減算の例(6502やPICやARMの場合)
MOV A, 2 ; Aレジスタに数値の2を読み込む
SUB A, 1 ; Aレジスタから数値1を減算する。結果は1になる。
  ; 結果が正なので、キャリーフラグは1になる。
数式2 減算を2に補数による加算で実現した場合
MOV A, 2 ; Aレジスタに数値の2を読み込む
ADD A, 0xF ; Aレジスタに15(1を2の補数化したもの)を加算する。結果は1になる。
  ; 桁あふれが発生するので、キャリーフラグは1になる。

6809やZ80や8086の場合、イミディエイトデータによる減算と、2の補数化したイミディエイトデータによる加算とでは、キャリーフラグが反転します。これは前項での説明の通りです。そのためイミディエイトデータによる減算を加算で代替することは、完全には出来ません。

ところが6502やPICやARMの場合、イミディエイトデータによる減算と、2の補数化したイミディエイトデータによる加算は全く同一の結果になります。そのため、あらかじめ減算したい数値を2の補数に変換しておく手間さえいとわなければ、イミディエイトデータによる減算命令を省略してしまうことができます。実際PICにはイミディエイトデータによる減算命令がありません。

TD4EX4でも状況は同じです。当初予定していたイミディエイトデータによる減算命令を削除してしまっても、加算で代用できるので問題ありません。そのため筆者はRAMへの書き込み命令を優先しました。

写真4 TD4EX4の構成
写真4 TD4EX4の構成