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

●SBB命令の計算方法の「理由」

前回([第196回])とその前の回([第195回])で、10進数の減算でも、引く数を「9の補数」+キャリーに置き換えることで、加算にしてしまうことができるというお話をしました。
そして下位桁からのボローを含めて減算するSBB命令の場合、(下位桁からの)ボローがあれば、それを反転して加算すればよい、という説明をしました。

下位桁からのボローが無い場合(キャリーフラグがクリアされている場合)には、それを反転させますから、キャリーの1を含めて加算を行います。これは結果的には、下位桁からのボローを無視するSUB命令と同じ計算をすることになります。
引かれる数+引く数の「9の補数」+1(反転させてONになったキャリー)、という計算です。

下位桁からのボローが有る場合は、そのボロー(キャリーフラグ)の状態を反転しますから、キャリーは含めないで加算することになります。
引かれる数+引く数の「9の補数」、という計算です。

前回、SBB命令では、上の説明のように、下位桁からのボロー(キャリー)の状態を反転させて、それを「9の補数」の計算に加えればよい、という計算ルールについて、「なぜそうすればよいか、という理由はわかりません」と書きました。

確かに最初はどうすればよいのか、すぐには思いつかなかったので、いろいろな例で計算を試みていくうちに、そうすればよい、ということがわかったのですけれど、でもそのあとで、「なぜ、そうすればよいのか」という、その理由についても考えて、それは解決していたのです。
そのことをすっかり忘れてしまっていました(うーん。やっぱり、痴呆が始まっているのか…。トホホ…)。

そんなに難しい理屈ではなかったのです。
ごく当たり前の小学校の算数でした。

下位桁からのボローを含めた減算は、引かれる数−引く数−1、という計算をします。
前回の計算例、423−142=281で、3桁目の計算が、その計算になります。
4−1−1(下位桁からのボロー)です。

ところで、この式の下位桁からのボローを引くところだけを後回しにして考えてみると、
4−1ですから、
ここはSUB命令のやり方で、
4+8(1の「9の補数」)+1、に置き換えることができます。

ここに、さきほど後回しにしていた、下位桁からのボローを引く部分をもとに戻すと、
4+8(1の「9の補数」)+1−1になります。

下位桁からのボローがあるときには、+1と−1で+1加算がなくなるので、4+8(1の「9の補数」)、という計算をすることになります。
下位桁からのボローが無いときには、+1が消されないので、そのまま+1加算が残ります。

以上を整理すると、下位桁からのボローがある場合には、+1加算をしないで計算し、下位桁からのボローが無い場合には、逆に+1加算をすればよい、ということになります。

●2進数でSBB命令の計算方法を確認してみる

SBB命令の減算を、「9の補数」とキャリーを使った加算に置き換えることができるということを、10進数での計算で確かめました。
2進数での計算についても、同じようにあてはまるはずですが、念のため、実際の計算例で確認してみることにします。

下位桁からのボローがある減算の確認ですから、16ビット、2バイトの数で考えてみることにします。
16進数2バイトの数の減算例です。
6543−34AB=3098
これは10進数に直すと、25923−13483=12440という計算をしていることになります。
この計算を、最初に下位バイト、次に上位バイトの順に行います。
下位バイトはSUB命令、上位バイトはSBB命令の計算です。

最初の下位バイトの減算です。

   2進数          16進数 
  01000011         43  
  10101011(−       AB(

という計算ですから、これを「1の補数」+キャリーに置き換えた加算で行います。

   2進数          16進数    10進数
  01000011         43       67
  01010100          54        84 
         1(+        1(+      1(
  10011000         98      152 

これで下位バイトが求まりました。なお10進数の計算は8ビットの計算の検算のために示したもので、2バイトの2進数の計算の一部としての意味は全くありません。

さて、上の計算では、上位桁へのキャリーは発生していませんから、その場合にはキャリー(減算ですからボロー)を立てることになります。
キャリーフラグがセットされます。

次に上位バイトの計算です。

   2進数          16進数 
  01100101         65
  00110100         34  
         1(−        1(− ……下位桁からのボロー

という計算ですから、これを「1の補数」に置き換えた加算で行います。
下位桁からのボローがある場合には、それを逆にして、キャリーフラグをクリアしてしまいますから、さきほどの計算の、+1する部分がなくなります。

   2進数          16進数    10進数
  01100101         65       101 
  11001011(+       CB(+     203(
1 00110000       1 30       304 

計算の結果発生した上位桁へのキャリーは、反転させますから、キャリーフラグをクリアすることになります。

以上の計算によって、2進数2バイトの減算が正しく行われることが、確認できました。

次回は、今まで考えてきた加算、減算のルールをもとにして、実際の回路の説明にとりかかります。
2009.4.4upload

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