.text
.globl __start
__start:
li $t1,9
li $t2,7
addi $t1,$t1,3
addi $t2,$t2,3
li $t3,0xFFFFFFFF
srl $t3,$t3,$t1
sll $t3,$t3,$t1
sll $t3,$t3,$t2
srl $t3,$t3,$t2
not $t3,$t3
li $s1,0x12345678 # input data in $s1 register
and $s2,$s1,$t3 # output data in $s2 register
li $v0,10
syscall # exit
1 に答える
not $t3,$t3
で終わるシーケンスは、端が 1 ビットで中央が 0 の AND マスクを作成するように見えます。したがって、一方の端に回転させてから中央のビットをノックアウトするのと同じことを行うことができます。それらをシフトアウトし、次に回転させます。
しかし、MIPS にはハードウェアのローテーション命令がありません。 ror
androl
は、2 回シフトして OR する疑似命令にすぎないため、これはより効率的ではありません。
AND マスクを作成して使用することは、2 つの入力間のビット範囲をゼロにする最良の方法です。しかし、マスクをより効率的に作成できる可能性があります。likeまたはそのようなもので、 one 、 two 、 one 、および one~((1<<high) - (1<<low))
を取ります。その式にはオフバイワンがあるかもしれません。これはあなたが本当に求めていたものではないので、確認しませんでした。li reg,1
sllv
subu
not
もちろん、ビット位置が既知の定数である場合は、アセンブル時に計算をli
行い、マスクを使用して実行する必要があります。(1 つまたは 2 つのハードウェア命令、またはandi
結果のマスクが下位 16 のビットのみを設定した場合でも。) 優れたアセンブラーを使用すると、定数を含む式を記述して、 のように評価できますli $t1, ~((1<<9) - (1<<7))
。しかし、たとえば MARS ではそれができません。ハードコーディングする必要があります0xfffffe7f