用移位和旋转寄存器替换“和”,结果和输入保持不变

问题描述

.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,$t2   
srl $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

解决方法

看起来以not $t3,$t3结尾的序列创建了一个AND掩码,其边沿为1位,而中间为零。因此,您可以执行相同的操作:先旋转中间的一端,然后将其移出,然后再旋转回去。


但是MIPS没有硬件旋转指令。 rorrol只是伪指令,它们会移位两次并进行“或”运算,因此效率将更高。

创建和使用AND掩码 可能是将两个输入之间的位范围归零的最佳方法。但是您可能可以更有效地构造遮罩。类似于~((1<<high) - (1<<low))或类似的东西,它需要一个li reg,1,两个sllv,一个subu和一个not。该表达式中可能有一个一一对应的内容。我没有检查,因为这不是您真正要问的。

或者当然,如果位的位置是已知的常数,则应该只在汇编时进行数学运算,并使用掩码运行一个li。 (1或2条硬件指令,或者如果生成的掩码仅将低位设置为16,甚至是andi。)一个好的汇编程序可以让您编写涉及常量的表达式并对其求值,例如li $t1,~((1<<9) - (1<<7)) 。但是,例如MARS不允许您这样做。您必须对0xfffffe7f

进行硬编码

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...