標準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
前へ
次へ
ホームページトップへ戻る