アセンブリ言語 CASL2 シフト演算の仕方と命令一覧
シフト演算と聞くと、足し算や引き算とどう違うの?と疑問に思うときがありますよね。
シフト演算は、かけ算や割り算を両立できる計算方法です。
今回は、アセンブリ言語CASL2のシフト演算命令とシフト演算のやり方について情報を共有したいと思います。
シフト演算命令
CASL2のシフト演算命令は「算術シフト」と「論理シフト」の2種類があります。
算術シフトと論理シフトでは計算結果がまったく違うので、他の命令よりも理解しやすはずです。
算術左シフト
名称 | オペコード | 第1オペランド | 第2オペランド | 第3オペランド |
Shift Left Arithmetic | SLA | レジスタ | アドレス | --- |
レジスタ | アドレス | レジスタ |
使用例1: SLA GR0, 1
汎用レジスタGR0の値を、1ビット左に算術シフトせよ。
使用例2: SLA GR0, 0, GR1
汎用レジスタGR0の値を、「汎用レジスタGR1の値 + 0」ビット左に算術シフトせよ。
使用例3: SLA GR0, A, GR1
汎用レジスタGR0の値を、「汎用レジスタGR1の値 + A」番地のアドレス値ビット分左に算術シフトせよ。
※ 通常は、使用例1か使用例2のようにしか使用しません。
使用例3で第2オペランドにアドレスを示すラベルAを指定していますが、キ○ガイな動作になるので使うのは止めましょう(一応動きます)。
算術右シフト
名称 | オペコード | 第1オペランド | 第2オペランド | 第3オペランド |
Shift Right Arithmetic | SRA | レジスタ | アドレス | --- |
レジスタ | アドレス | レジスタ |
使用例1: SRA GR0, 1
汎用レジスタGR0の値を、1ビット右に算術シフトせよ。
使用例2: SRA GR0, 0, GR1
汎用レジスタGR0の値を、「汎用レジスタGR1の値 + 0」ビット右に算術シフトせよ。
論理左シフト
名称 | オペコード | 第1オペランド | 第2オペランド | 第3オペランド |
Shift Left Logical | SLL | レジスタ | アドレス | --- |
レジスタ | アドレス | レジスタ |
使用例1: SLL GR0, 1
汎用レジスタGR0の値を、1ビット左に論理シフトせよ。
使用例2: SLL GR0, 0, GR1
汎用レジスタGR0の値を、「汎用レジスタGR1の値 + 0」ビット左に論理シフトせよ。
論理右シフト
名称 | オペコード | 第1オペランド | 第2オペランド | 第3オペランド |
Shift Right Logical | SRL | レジスタ | アドレス | --- |
レジスタ | アドレス | レジスタ |
使用例1: SRL GR0, 1
汎用レジスタGR0の値を、1ビット右に論理シフトせよ。
使用例2: SRL GR0, 0, GR1
汎用レジスタGR0の値を、「汎用レジスタGR1の値 + 0」ビット右に論理シフトせよ。
シフト演算とは?
そもそもシフト演算とはどういった計算なのか?
シフト演算は、例えば4という値を1桁分左にシフトすると2倍の8に、右にシフトすると1/2倍の2にする演算方法です。
シフト演算には「右シフト」と「左シフト」の2種類の計算方法があります。
例えば、ある数を左に1桁シフトすると2倍に、右に1桁シフトすると1/2倍にすることができます。
例1: 2進数(0100)2を、右または左に1ビットシフトすると(0100)2はどうなる?
① 右シフトの場合- 0100 --1ビット右シフト--> 0010
答え: (0010)2 = (2)10
右に1ビットシフトすると元の数値の1/2倍になります。
4 / 2 = 2
※ 右シフトの場合、1番右の桁は無くなり、1番左の桁に0を補います。
② 左シフトの場合
- 0100 --1ビット左シフト--> 1000
答え: (1000)2 = (8)10
左に1ビットシフトすると元の数値の2倍になります。
4 × 2 = 8
※ 左シフトの場合、1番左の桁は無くなり1番右の桁に0を補います。
したがって、右に1ビットシフトした場合1/2倍になり、左なら2倍ということになります。
算術シフト・論理シフトの違い
算術シフトと論理シフトの違いは、最上位桁の扱い方に違いがあります。
論理シフトは、最上位ビットも含めたすべての桁がシフトされます。
一方で、算術シフトは最上位ビット以外のすべての桁がシフトされます。
更にいうと、算術シフトはマイナスの数を扱えますが、論理シフトはマイナスの数を扱えません。
それでは具体的にどのような違いがあるのか見てみましょう。
論理シフトによる演算
例2: GR0の値が(1000 0000 0000 0001)2のとき1ビット左右いずれかに論理シフトするとどうなるか?
① 論理左シフトの場合- 1000 0000 0000 0001 --1ビット論理左シフト--> 0000 0000 0000 0010
論理左シフトは、最上位ビットも含めた全ての桁をシフトします。
② 論理右シフトの場合
- 1000 0000 0000 0001 --1ビット論理右シフト--> 0100 0000 0000 0000
論理右シフトも、最上位ビットも含めた全ての桁をシフトします。
算術シフトによる演算
例3: GR0の値が(1000 0000 0000 0001)2のとき1ビット左右いずれかに算術シフトするとどうなるか?
① 算術左シフトの場合
- 1000 0000 0000 0001 --1ビット算術左シフト--> 1000 0000 0000 0010
算術左シフトは、最上位ビットを除いた全ての桁をシフトします。
② 算術右シフトの場合
- 1000 0000 0000 0001 --1ビット算術右シフト--> 1100 0000 0000 0000
算術右シフトは、最上ビットが引き継がれシフトされます。
算術右シフトは最上位ビットが引き継がれる
算術右シフトは、最上位ビットがシフトする度に連なる形でシフトされます。
例4. GR0の値が(1000 0000 0000 0000)2のとき、2、3、4ビット算術右シフトするとどうなるか?
【最上位ビットが引き継がれる算術右シフト】
- 1000 0000 0000 0000 --右に2ビット算術シフト--> 1110 0000 0000 0000
- 1000 0000 0000 0000 --右に3ビット算術シフト--> 1111 0000 0000 0000
- 1000 0000 0000 0000 --右に4ビット算術シフト--> 1111 1000 0000 0000
以上のように、最上位ビットの値が次々と引き継がれる形でシフトされます。
なぜ、最上位ビットが右シフトする度に連なるのかというと、算術右シフトの場合、マイナスの数を表現した結果、最上位ビットが次桁に引き継がれているように見える、というのが理由です。
2進数でマイナスの数がどのように表現されているかを理解することで、この謎が解けるはずです。とはいえ、まずは形から入ることで、徐々に理解が追いついてくるため急ぐ必要は全くありません。
以下の「16進数のマイナスの数」の記事は、16進数のマイナスの数について触れた記事ですが、2進数とも大きく関わっているため、興味があれば参考にしてみてください。
さいごに
シフト演算命令は、算術と論理で計算結果がまったくことなるので判別がつきやすいですよね。
それでは次回にお会いしましょう。