CASL U - プログラミングの基礎(算術,論理等演算命令) |
ADDA命令(算術加算)の代わりにADDL命令(論理加算)、SUBA命令(算術減算)、SUBL命令(論理減算)、AND命令(論理積)、OR命令(論理和)、XOR命令(排他的論理和)を使うことができる。
命令例 動作 ADDA GR0, DATA1 実効アドレスに記憶されている内容とGR0の内容を加算してGR0に格納する。
実効アドレスはDATA1番地である。ADDA GR2, DATA1, GR1 実効アドレスに記憶されている内容とGR2の内容を加算してGR2に格納する。
実効アドレスは(DATA1番地+GR1の内容)である。
(A) 加算・減算命令
加算命令と減算命令には算術と論理がある。例えば、算術加算では負数を考慮して計算され、論理加算では負数はないものとして計算される。減算でも同じである。
例 7000(16) + 1000(16) を算術加算と論理加算で計算する。
算術加算の計算結果は、7000(16) + 1000(16) = 8000(16) である。負数を扱うので答えは−32768(10)ということになる。FRはOF=1(正数は7FFFまでであり、この値を超えたため)、SF=1(計算結果が負数となったため)となる。
論理加算の計算結果は、7000(16) + 1000(16) = 8000(16) である。負数を扱わないので答えは32768(10)ということになる。FRはSF=1(計算結果が負数となったため)となる。
算術加算と論理加算ともに計算結果は8000(16) であるが、FRの状態が違う。算術減算と論理減算も同じである。扱える値の範囲を考えて選択する必要がある。
例題2-1 23(16) + 45(16) を計算する。値は2つともメモリに記憶させておく。計算結果はKOTAE番地に記憶する。
EX21 START LD GR0, DATA1 ADDA GR0, DATA2 ;ADDL GR0, DATA2 ST GR0, KOTAE RET DATA1 DC #0023 DATA2 DC #0045 KOTAE DS 1 END
計算結果は 23(16) + 45(16) = 68(16) である。
3行目のADDA命令をADDL命令に置き換えても計算結果及びFRの状態は同じである。
6, 7行目のDC命令で定義する値が16進定数のとき4けたで書く必要がある。 DATA1 DC #23 はエラーとなる。
次のリストは計算データをレジスタに直接与えた例である。使用するメモリ量はEX21と同じである。
EX21B START LD GR0, =#0023 ADDA GR0, =#0045 ;ADDL GR0, =#0045 ST GR0, KOTAE RET KOTAE DS 1 END
例題2-2 23(16) + 45(16) を計算する。値は2つともメモリに記憶させておく。計算結果はKOTAE番地に記憶する。指標レジスタを使用する。
EX22 START LD GR1, =1 LD GR0, DATA1 ADDA GR0, DATA1, GR1 ;ADDL GR0, DATA1, GR1 ST GR0, KOTAE RET DATA1 DC #0023 DC #0045 KOTAE DS 1 END
GR1を指標レジスタに使用している。2行目でGR1に1を格納している。
4行目の加算命令で指標レジスタを使用している。ここの実効アドレスは(DATA1番地+GR1の内容)である。23(16) と 45(16) のデータは連続して書く必要がある。
加算・減算命令とロードアドレス命令について
(B) 論理積、論理和、排他的論理和
論理積、論理和、排他的論理和は次の真理値表に従って計算する。
論理積 論理和 排他的論理和
A B Y 0 0
0 1
1 0
1 10
0
0
1
A B Y 0 0
0 1
1 0
1 10
1
1
1
A B Y 0 0
0 1
1 0
1 10
1
1
0
(例) 23(16) AND 45(16)
次のように2進数になおして、各ビットを真理値表に従って計算する。
23(16) → 0000 0000 0010 0011(2)
45(16) → 0000 0000 0100 0101(2)
0000 0000 0000 0001(2) → 1(16) となる。
(例) 23(16) OR 45(16)
23(16) → 0000 0000 0010 0011(2)
45(16) → 0000 0000 0100 0101(2)
0000 0000 0110 0111(2) → 67(16) となる。
(例) 23(16) XOR 45(16)
23(16) → 0000 0000 0010 0011(2)
45(16) → 0000 0000 0100 0101(2)
0000 0000 0110 0110(2) → 66(16) となる。
例題2-3 23(16) AND 45(16) を計算する。値は2つともメモリに記憶させておく。計算結果はKOTAE番地に記憶する。
EX23 START LD GR0, DATA1 AND GR0, DATA2 ST GR0, KOTAE RET DATA1 DC #0023 DATA2 DC #0045 KOTAE DS 1 END
例題2-1、3行目のADDA命令をAND命令に変えただけである。
(c) シフト演算命令
シフト演算は、算術シフト演算と論理シフト演算がある。
算術シフト演算命令はSLA(Shift Left Arithmetic, 算術左シフト)とSRA(Shift Right Arithmetic, 算術右シフト)である。
この演算は、符号を除きレジスタGRの内容を実効アドレスで指定したビット数だけ左または右にシフトする。シフトの結果、空いたビット位置には、左シフトのときは0、右シフトのときは符号と同じものが入る。(下図参照)
GR0=01010101 01010101(2)=5555(16)
GR1=10101010 10101010(2)=AAAA(16)
GR2=00000000 00000001(2)=0001(16) とする。
命令例 動作 SLA GR0, 2 GR0の内容を2ビット左にシフトする。
演算結果は01010101 01010100(2)となる。SLA GR1, 2, GR2 GR1の内容を(2+GR2)ビット、すなわち3ビット左にシフトする。
演算結果は11010101 01010000(2)となる。SRA GR0, 2 GR0の内容を2ビット右にシフトする。
演算結果は0001010101010101(2)となる。SRA GR1, 1, GR2 GR1の内容を(1+GR2)ビット、すなわち2ビット右にシフトする。
演算結果は11101010 10101010(2)となる。
論理シフト演算命令はSLL(Shift Left Logical, 論理左シフト)とSRL(Shift Right Logical, 論理右シフト)である。
この演算は、符号を含みレジスタGRを実効アドレスで指定したビット数だけ左または右にシフトする。シフトの結果、空いたビット位置には0が入る。(下図参照)
GR0=01010101 01010101(2)=5555(16)
GR1=10101010 10101010(2)=AAAA(16)
GR2=00000000 00000001(2)=0001(16) とする。
命令例 動作 SLL GR0, 2 GR0の内容を2ビット左にシフトする。
演算結果は01010101 01010100(2)となる。SLL GR1, 2, GR2 GR1の内容を(2+GR2)ビット、すなわち3ビット左にシフトする。
演算結果は01010101 01010000(2)となる。SRL GR0, 2 GR0の内容を2ビット右にシフトする。
演算結果は0001010101010101(2)となる。SRL GR1, 1, GR2 GR1の内容を(1+GR2)ビット、すなわち2ビット右にシフトする。
演算結果は00101010 10101010(2)となる。
算術シフト演算または論理シフト演算の結果によってFRのSFとZFが設定される。FRのOFはあふれ出たビットが設定される。
例題2-4 23(16) を左に1ビット算術シフトする。値はメモリに記憶させておく。計算結果はKOTAE番地に記憶する。
EX24 START LD GR0, DATA1 SLA GR0, 1 ST GR0, KOTAE RET DATA1 DC #0023 KOTAE DS 1 END
計算結果は46(16)となる。この値(23(16))であれば算術シフトでも論理シフトでも結果は同じである。処理する値によって算術シフトか論理シフトを適切に選択する必要がある。
左に1ビットシフトすると元の値の2倍、2ビットシフトすると4倍というように倍々になる。ただし、オーバーフローが起こらないようにする必要がある。同じように、右に1ビットシフトすると1/2倍、2ビットシフトすると1/4倍になる。
GR0 = 0000 0000 0000 1000(2) = 0008(16) =
GR0 = 0000 0000 0001 0000(2) = 0010(16) =
GR0 = 0000 0000 0010 0000(2) = 0020(16) =
GR0 = 0000 0000 0100 0000(2) = 0040(16) =
GR0 = 0000 0000 1000 0000(2) = 0080(16) =
GR0 = 0000 0001 0000 0000(2) = 0100(16) =
GR0 = 0100 0000 0000 0000(2) = 4000(16) =
GR0 = 0000 0000 0000 0000(2) オーバーフロー8(10)
16(10)
32(10)
64(10)
128(10)
256(10)
16384(10)
↓ 1ビット左シフト
↓ 1ビット左シフト
↓ 1ビット左シフト
↓ 1ビット左シフト
↓ 1ビット左シフト
↓ 6ビット左シフト
↓ 1ビット算術左シフト
(d) 比較演算命令
比較演算は、CPA(ComPare Arithmetic, 算術比較)とCPL(ComPare Logical ,論理比較)命令がある。比較の結果は次のようにFRに設定される。
比較演算 | 比較結果 | FRの値 | ||||
SF | ZF | OF | ||||
算術比較 | CPA r1, r2 | (r1)>(r2) (r)>(実効アドレス) |
0 | 0 | 0 | |
CPA r, adr [,x] | ||||||
(r1)=(r2) (r)=(実効アドレス) |
0 | 1 | 0 | |||
論理比較 | CPL r1, r2 | |||||
(r1)<(r2) (r)<(実効アドレス) |
1 | 0 | 0 | |||
CPL r, adr [,x] |
GR0=01010101 01010101(2)=5555(16)=21845
GR1=10101010 10101010(2)=AAAA(16)=-21846=43690 とする。
命令例 動作 CPA GR0, GR1 GR0の内容とGR1の内容を比較する。
GR0=21845 > GR1=-21846
演算結果は SF=0, ZF=0 となる。CPL GR0, GR1 GR0の内容とGR1の内容を比較する。
GR0=5555(16) < GR1=AAAA(16)
演算結果は SF=1, ZF=0 となる。
比較演算では、結果がFRに設定されるだけである。FRの設定値を利用(参照)するにはジャンプ命令を使う。
CASL U | Copyright © 2003,2017 Hiroshi Masuda |