对于已知常量 AND 掩码,仅使用移位和旋转的逻辑 AND

Logical AND using only shift and rotate, for a known constant AND mask

我想仅用移位和循环指令替换以下指令集(在汇编 MIPS 中)中的“AND”,并且显然对任何单词都有相同的结果

.text
main:
        la $a0,input            
        lw $t1,0($a0)           
        li $t0,0xFFF00FFF   #mask
        and $t2,$t1,$t0     
        li $v0,10
        syscall
        .data
input:  .word 0x12345678

我知道这个特殊面具的答案如下:

ror $t2, $t1, 9
srl $t2, $t2, 17
ror $t2, $t2, 6

我想知道上面的shifts/rotations是怎么计算的

二进制输出为:

input : 00010010001101000101011001111000 ($t1)
mask  : 11111100000000000000000111111111 ($t0)

output: 00010000000000000000000001111000 ($t2)

您正在利用以下事实:移位(逻辑)将移入 0 位并丢弃移出的位,而旋转将保留所有位并将移出的位带回另一端。因此,常量 AND 掩码将变为掩码中每个 0 范围的移位和每个 1 范围的旋转,总 shift/rotate 计数为 32。

要计算 shifts/rotates,您只需找到掩码中所有 0 或 1 的范围,然后按该数量移动或旋转。您可以从遮罩底部开始(使用 ror/srl)或从遮罩顶部开始(使用 rol/sll)

所以对于掩码 0xfff00fff,从底部开始,你有 12 个 1,然后是 8 个 0,然后是 12 个 1,给出

ror $t2, $t1, 12
srl $t2, $t2, 8
ror $t2, $t2, 12

对于具有交替位(如 0x55555555)的掩码的最坏情况,您最终会得到总共 32 次(交替)移位和旋转,每次移位 1 位。