標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第193回]

●減算命令の回路の説明です

前回に引き続いて、ALU回路の説明をいたします。
前回は加算命令とキャリーフラグについて、考えました。
今回は減算命令の回路について、考えてみます。

減算命令の回路というと、加算命令の回路に対して、何か別の回路があるような感じを受けてしまいますが、実は加算回路をそのまま利用します。
前回の加算命令の説明の中にそのヒントがあります。

前回のいろいろな数の加算の例の中に、正の数と負の数の加算、というのがありました。

   2進数          16進数     10進数
  01010110         56        86 
  11001110(+       CE(+     206(+ 
1 00100100       1 24        292 

という計算でした。
これは符号無しの2進数として考えましたが、符号付の2進数として考えると、
CEは符号付の数では−50になりますから、上の計算は、86+(−50)=36という計算になります。
これは結局、86−50=36という減算をしているのと同じです。
つまり、加算回路を利用して、減算をすることが可能なのです。

ただし、加算とちがって、減算では、前準備が必要です。
上の例でいうと、86から50を引くために、まず−50という数を準備しなくてはなりません。
10進数ならば、数値の前にマイナス符号をつけるだけで済みますが、2進数では、そういうわけにはいきません。

[第14回]で「2の補数」について説明をしました。
2進数の減算では、引く数の「2の補数」をまず求めて、それを引かれる数に加算する、という計算をします。
減算を行うための準備として、引く数の負数を求めるということは、その数の「2の補数」を求めることと同じです。
では、「2の補数」というのは、どうすれば求めることができるでしょう?

これも[第14回]で説明をしました。
「2の補数」を求めるには、まずもとの数をビット毎に、1と0を逆にします。
上の例の50は16進数では32になりますから、00110010です。
この1と0を全てひっくり返します。
11001101です。これが1の補数です。

1の補数に、さらに1を加えます。11001110になります。16進数表記ではCEです。
これが16進数の32(00110010)の「2の補数」です。
前回の計算例の説明で、CEは10進数の−50である、として計算を行い、結果に間違いのないことを確認しました。
ですから、減算を行うには、引く数の1と0をひっくり返して(つまりその数の逆の数、NOTを求めて)それに+1を加えたものと、引かれる数との間の加算を行えばよい、ということがわかります。

[第179回]の「ALUのレジスタ”A”とレジスタ”B”の回路図」で、レジスタ”B”の前にインバータ74HC04によって、全部のビットを反転したものを、選択できるようにしてあるのは、そのためなのです。
ここでも、[第191回]でデータシートをお見せした74HC157を使っています。
INVsel信号をアクティブ(L)にすると、そのとき内部データバスにある値の各ビットの1と0を反転したものが、レジスタ”B”への入力として選択されます。

しかし、これは「1の補数」です。「2の補数」ではありません。
では、どうすれば、ここから、「2の補数」が求まるのでしょうか?
あ。これは、次回までの宿題ということにしましょうか。

じつは、この質問は意地の悪い質問です。
「IQサプリ」的な質問ですね。
もう少し親切な質問は、下のようになります。

どうすれば、「1の補数」を利用して、加算回路で減算を行うことができるでしょうか?
ヒントは前回の加算についての説明の中にあります。

現在、最終的な基板配線図の修正作業中です。
めちゃめちゃ大変です。
もう、ムリムリで追加配線などできそうにないところを、あちこち配線を引越しさせたりしながら作業をしています。
超巨大な迷路の中で、もがいているような感じです。
でも、のってくると、つい時間が経つのを忘れて没頭してしまいます。

記事の更新が、細切れ状態なのは、そういう事情からです。
2009.3.28upload

前へ
次へ
ホームページトップへ戻る