ローテート
ぐるんと回す
シフト命令と類似した命令で、ローテートと呼ばれるものがあります
ローテートは、ビット列を左右にずらすという意味ではシフトと同じですが
その関係は、環(わ)になっていると考えることができます
ローテートは、左右にシフトしてあふれた1ビットを尾にくっつけます
つまり、端にあった1ビットがぐるんと一週して反対側に付加されるということです
ローテートには、キャリーフラグを通してビットを1週するローテートと
キャリーフラグを通さないで1週する2種類の方法があります
ただし、どちらの方でも溢れた1ビットはキャリーフラグにセットされます
キャリーを通さない
|
---|
1 | 0 | 1 | 1 | 0 | 1 | 0 | 1
|
---|
↓右に1ローテート
|
---|
1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | --CFにセット--> | CF
|
---|
↑ | | ↓
|
<-----------------------
|
---|
キャリーを通す
|
---|
1 | 0 | 1 | 1 | 0 | 1 | 0 | 1
|
---|
↓右に1ローテート
|
---|
? | 1 | 0 | 1 | 1 | 0 | 1 | 0
|
---|
↑ | | ↓
|
<------ | CF | <------
|
---|
キャリーを通していた場合、?には元のキャリーの値が入ります
キャリーフラグを通さない左ローテートはROL、右ローテートはROR
キャリーフラグを通す左ローテートはRCL、右ローテートはRCRです
オペランドの関係は、シフト命令と同じです
-A 100
15F2:0100 MOV AL , FF
15F2:0102 RCR AL , 1
15F2:0104
-G =100 104
AX=007F BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=0104 OV UP EI NG NZ AC PO CY
このプログラムを実行するまえ、CFフラグは 0 だったと仮定しています
すると、ビット列 1111 1111 をキャリー経由で右ローテートすると
1がCFにセットされ、元のCFの値 0 がビット列のMSBにセットされます
次のプログラムはキャリーを通さない左ローテートのプログラムを
トレースすることで、ローテートの関係を明確にした例です
-A 100
15F2:0100 MOV AL , C0
15F2:0102 ROL AL , 1
15F2:0104 ROL AL , 1
15F2:0106
-T =100 3
AX=00C0 BX=0000 CX=0002 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=0102 NV UP EI NG NZ AC PO NC
15F2:0102 D0C0 ROL AL,1
AX=0081 BX=0000 CX=0002 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=0104 NV UP EI NG NZ AC PO CY
15F2:0104 D0C0 ROL AL,1
AX=0003 BX=0000 CX=0002 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=0106 OV UP EI NG NZ AC PO CY
ビット列の最上位ビットが、最下位ビットに回っているのがわかりますね
1100 0000 が 1000 0001 となり、さらに 0000 0011 となっています
この時、ローテートの対象となる最上位ビットがキャリーにセットされているのも確認できます