移位指令
移位操作包括逻辑左移指令,逻辑右移指令,算术右移指令,最多能将寄存器中的值左移或右移31位。
MIPS中有位数不可变的移位指令,也有位数可变的移位指令。
移位与乘除2的幂次的关系不再赘述。
位数不可变的移位指令
需注意,位数不可变的移位指令虽然是以常数作为移位数,但却是一个R-类型指令,移位数在机器语言形式的指令中占shamt位,rs固定为0,是不起作用也不用写出的操作数。
逻辑左移指令
指令操作码为sll,将低位补0。方便记忆,我把其全称看作shift left logical。
sll $s1, $s2, 4
示例中的指令意为将 $s2
寄存器中的值左移四位并存到$s1
中。其中$s1
所处位置的操作数在机器码中的表示为rd,是目的寄存器,$s2
所处位置的操作数在机器码中的表示为rt,是源寄存器。
逻辑右移指令
指令操作码为srl,高位补0。方便记忆,我把其全称看作shift right logical。使用方法与sll一致。
算术右移指令
指令操作码为sra,高位按符号部位,正数补0,负数补1。方便记忆,我把其全称看作shift right arithmetic。使用方法与sll一致。
我在这里阅读时产生过疑问,关于移位指令中rt,rd可不可以是同一个寄存器的问题。阅读到后面,发现有这样的示例。add指令也有这样的示例,推测大部分甚至可能是全部R-指令,I-指令应该都可以把rt,rs,rd中的2位或3位(当然 I-指令没有rs项)用相同的寄存器来进行操作。
位数可变的移位指令
位数可变的移位指令中shamt固定为0,rs作为移位数,出现在指令中。有可变逻辑左移指令(sllv),可变逻辑右移指令(srlv),可变算术右移指令(srav)。之所以称为可变,是因为这里的移位数成为变量,我们不必再手动输入确定的常数来进行移位。
sllv $s3, $s2, $s1
需注意,这里$s1
为移位数,在机器码中的表示为rs,$s2
为被移位数,在机器码中的表示为rt。这与我们之前看到的R-指令中汇编语言各操作数顺序与机器码中操作数的顺序不相同了,我想MIPS中这些顺序对应关系并没有什么定律,决定操作数是rs,rt还是rd的是指令的意义。
乘除指令
乘法(mult)与除法(div)指令和加减并不相同。两个32位数相乘得到64位数,相除得到32位的商与32位的余数。
MIPS中用两个特殊的寄存器作为乘除法的目的寄存器,分别为hi和lo。(我把这两个看作high和low)。乘法结果的高32位保存在hi中,低32位保存在lo中。除法的商存放在lo中,余数存放在hi中。目的寄存器是确定的,指令也就不用再写明目的寄存器了。
mult $s1, $s2