ニッシー
1990年生まれ
血液型 O型

こんにちは。ITブログアルケーナム管理人のニッシーです。

詳細プロフィールへ

お問い合わせへ






2018-06-10

CASL2の加算・減算命令の種類







CASL2で、足し算や引き算するためには、専用の命令を使用することで計算することができます。


COMET2に限らず、実はコンピュータは足し算のみで全ての計算を行うことが可能です。


今回は、「加算・減算」命令について触れたいと思います。
















加算命令



CASL2では、加算命令は2種類用意されており、それぞれ「算術加算」と「論理加算」と呼ばれます。


算術加算と論理加算は、ほとんど同じ動作をし、同じ結果を返す命令ですが、数値の扱い方に明確な違いがあります。



算術加算



名称オペコード第1オペランド第2オペランド第3オペランド
ADD
Arithmetic
ADDAレジスタ
アドレス
or
レジスタ
---
レジスタアドレスレジスタ

使用例1: ADDA GR0, A

汎用レジスタGR0のデータとメモリA番地のデータを加算して、汎用レジスタGR0に転送せよ。



使用例2: ADDA GR0, 1

汎用レジスタGR0のデータとメモリ1番地のデータを加算して、汎用レジスタGR0に転送せよ。



使用例3: ADDA GR0, 1, GR1

汎用レジスタGR0のデータとメモリ汎用レジスタGR1のデータ+1番地のデータを加算して、汎用レジスタGR0に転送せよ。



使用例4: ADDA GR0, GR1

汎用レジスタGR0のデータと汎用レジスタGR1のデータを加算して、汎用レジスタGR0に転送せよ。



論理加算



名称オペコード第1オペランド第2オペランド第3オペランド
ADD
Logical
ADDLレジスタ
アドレス
or
レジスタ
---
レジスタアドレスレジスタ

使用例1: ADDL GR0, A

汎用レジスタGR0のデータとメモリA番地のデータを加算して、汎用レジスタGR0に転送せよ。



使用例2: ADDL GR0, 1

汎用レジスタGR0のデータとメモリ1番地のデータを加算して、汎用レジスタGR0に転送せよ。



使用例3: ADDL GR0, 1, GR1

汎用レジスタGR0のデータとメモリ汎用レジスタGR1のデータ+1番地のデータを加算して、汎用レジスタGR0に転送せよ。



使用例4: ADDL GR0, GR1

汎用レジスタGR0のデータと汎用レジスタGR1のデータを加算して、汎用レジスタGR0に転送せよ。





算術加算・論理加算の違い



算術加算・論理加算の違いは、フラグレジスタの示す値で判断することができます。


以下に具体的例を示します。


例1:5 + (-1) の計算

① ADDA(算術加算)で計算した場合

1 ADD START 
2   LAD GR0, 5 
3   LAD GR1, -1 
4   ADDA GR0, GR1 
5   RET 
6   END 

答え: (0004)16



② ADDL(論理加算)で計算した場合

1 ADD START 
2   LAD GR0, 5 
3   LAD GR1, -1 
4   ADDL GR0, GR1 
5   RET 
6   END 

答え: (0004)16



①と②の答えはADDA、ADDLともに4であり、全く同じ値がレジスタに格納されています。全く同じ計算結果であるため、2種類用意するメリットがあるのか疑問が残るところですが、フラグレジスタの状態に違いがあります。


①は、オーバーフローフラグが0のままであるのに対し、②は、オーバーフローフラグが1という明確な違いがあります。



①・・・OF(オーバーフローフラグ) = 0

【フラグレジスタ】
ZFSFOF
000



②・・・OF = 1

【フラグレジスタ】
ZFSFOF
001



なぜ算術加算・論理加算は同じ答えでもフラグに違いがあるのか



算術加算・論理加算においてフラグに違いがある理由は、算術と論理では16進数の扱いに違いがあるためです。


ここで、10進数「-1」は16進数「FFFF」ですが、この16進数「FFFF」は10進数「65535」でもあります。


  • -1 = (FFFF)16
  • 65535 = (FFFF)16


どちらも同じFFFFであるため、算術加算・論理加算は共に同じ答えを導き出してしまう、という理由があります。しかし、-1と65535の区別を行わないと、加算する際にCOMET2が混乱してしまいます。


COMET2さん「このFFFFは、-1なの? 65535なの? わかるか、ボケ~」


このような理由から、16進数FFFFはADDAにおいては-1として、ADDLにおいては65535として扱う決まりになっています。


  • ADDAのとき ・・・(FFFF)16-1として扱う
  • ADDLのとき ・・・(FFFF)1665535として扱う


このように、似たような命令を2種類用意することで、(FFFF)16の区別を行いたいということなんですね。


当然、16ビットにおいて65535は最大の数であり、これに加算を行えば数値がオーバーフローしてしまうことで、結果としてフラグレジスタの値に違いが出たというわけです。


それでは、なぜ、16進数では-1と65535が同じ表現になってしまうのか?それについては16進数のカラクリが関係しています。













減算命令



減算命令も「算術減算」と「論理減算」に分けることができます。


加算命令と同じく算術と論理の2種類の命令を用意することで、数値の扱い方に違いを持たせるためです。



算術減算



名称オペコード第1オペランド第2オペランド第3オペランド
SUBtract
Arithmetic
SUBAレジスタ
アドレス
or
レジスタ
---
レジスタアドレスレジスタ

使用例1: SUBA GR0, A

汎用レジスタGR0のデータとメモリA番地のデータを減算して、汎用レジスタGR0に転送せよ。



使用例2: SUBA GR0, 1

汎用レジスタGR0のデータとメモリ1番地のデータを減算して、汎用レジスタGR0に転送せよ。



使用例3: SUBA GR0, 1, GR1

汎用レジスタGR0のデータとメモリ汎用レジスタGR1のデータ+1番地のデータを減算して、汎用レジスタGR0に転送せよ。



使用例4: SUBA GR0, GR1

汎用レジスタGR0のデータと汎用レジスタGR1のデータを減算して、汎用レジスタGR0に転送せよ。



論理減算



名称オペコード第1オペランド第2オペランド第3オペランド
SUBtract
Logical
SUBLレジスタ
アドレス
or
レジスタ
---
レジスタアドレスレジスタ

使用例1: SUBL GR0, A

汎用レジスタGR0のデータとメモリA番地のデータを減算して、汎用レジスタGR0に転送せよ。



使用例2: SUBL GR0, 1

汎用レジスタGR0のデータとメモリ1番地のデータを減算して、汎用レジスタGR0に転送せよ。



使用例3: SUBL GR0, 1, GR1

汎用レジスタGR0のデータとメモリ汎用レジスタGR1のデータ+1番地のデータを減算して、汎用レジスタGR0に転送せよ。



使用例4: SUBL GR0, GR1

汎用レジスタGR0のデータと汎用レジスタGR1のデータを減算して、汎用レジスタGR0に転送せよ。



算術減算・論理減算に関しても、加算命令と同じように、OF(オーバーフローフラグ)の値の違いによって区別できます。




例2:0 - 5 の計算

  • SUBA(算術減算)で計算した場合 ・・・マイナスの数も扱える(-32768~32767の範囲)ため、OFは0のまま変化しません。
  • SUBL(論理減算)で計算した場合 ・・・0未満の数字を扱えない(0~65535の範囲)ため、OFが1に変化します。





ロードアドレス命令を用いた加算・減算



ロードアドレス命令は、指標修飾を利用することで加算・減算を行うことができます。


ロードアドレス命令の利点としてメモリに値を設定しないため、加算・減算命令を使用するときと比べ、1語分の節約につながります。また、ロードアドレス命令を使った加算・減算の表現は基本情報技術者試験に出題されているのを見たことがありますから覚えておいて損は無いでしょう。




しかし、指標修飾にGR0を使用できないため、GR0に入っているデータに加算や減算ができないところが難点といえます。





ロードアドレス命令を用いた加算



まず、ロードアドレス命令で加算する場合を見てみましょう。


例3: GR1の値に1を加算

1 LAD GR1, 1, GR1


このように第1オペランド第3オペランドに同じレジスタを設定します。



ロードアドレス命令を用いた減算



次に、減算する場合を見てみましょう。


例4: GR1の値から1を減算

1 LAD GR1, -1, GR1


ここで、インクリメントはある値に+1することで、デクリメントはある値から-1することをいいます。


  • インクリメント ・・・ある値に +1すること
  • デクリメント ・・・ある値から -1すること





通常の加算・減算命令と異なる動作をする



LAD命令を用いた加算・減算は、通常の加算命令や減算命令とはフラグレジスタの動作が異なります。


ここで、ADDA、ADDL、そしてLAD命令で加算した場合のフラグレジスタの動作を見てみましょう。





例5: GR1の値が(FFFF)16のとき、ADDA、ADDL、LAD命令でインクリメントする場合フラグレジスタはどうなる?

① ADDA命令で加算した場合

1 ADDA GR1, =1

【フラグレジスタ】
ZFSFOF
100


ADDA命令を用いた加算の場合、1 + (-1)を行っており、答えが0になるため、ZFが1になります。



② ADDL命令で加算した場合

1 ADDL GR1, =1

【フラグレジスタ】
ZFSFOF
101


ADDL命令を用いた加算の場合、65535((FFFF)16)を超えるためOF1になります。


また、COMET2は、16ビットなので、65535 + 1を行うと65536にはならず元に戻って答えが0になる(1 + (-1) と結果は同じ)ため、①のADDA命令同様にZFが1になります。



③ LAD命令で加算した場合

1 LAD GR1, 1, GR1

【フラグレジスタ】
ZFSFOF
000


LAD命令を用いた加算の場合フラグレジスタに変化はありません。





最後に



算術加算・論理加算は、僅かな違いがややこしいですね。ただ足し算、引き算するだけなのにめんどうくせぇ~。


続きはまた次回にご期待を!














プロフィール

ニッシー
1990年生まれ
血液型 O型

こんにちは。ITブログアルケーナム管理人のニッシーです。

詳細プロフィールへ

お問い合わせへ