(1) 32比特立即数的操作
MIPS有一个指令:load upper immediate(lui)。这个指令专门用于设置寄存器中常数的高16位。这样后续的指令可以设置常数的低16位。
例如:MIPS如何将0000 0000 0011 1101 0000 1001 0000 0000存入一个寄存器呢?
第一步:使用lui将高16位存入寄存器
lui $s0, 61 (61是高16比特的10进制数值)
第二步:加上低16位比特
ori $s0, $s0, 2304 (2304是低16位比特的10进制数值)
注意:此处用的是logical or immediate指令,而不是addi指令。addi指令会用16比特立即数的最左端的一位比特填充一个字的高16位。
(2) 分支和跳转的寻址
条件分支指令中的地址长度是16比特,这就意味着所有程序都不能超过2^16,然而这是不现实的。一种方法是借用一个特定的寄存器,用寄存器的值加上分支要跳转的地址来计算最终的目的地址:
PC = Register + Branch address.
因为PC中的地址就是当前指令的地址,如果用PC的值加在branch address上来寻址的话,可以跳转到距离当前指令正负2^15个字的范围内。几乎所有的loop和if语句的大小都小于2^16个word,所以PC是最合适的选择。这种branch addressing被叫做PC-relative addressing。实际上,MIPS的分支寻址是相对于下一条指令(PC+4)来讲的,而不是相对于PC。因为硬件实现时,在PC指向下一条指令之前,它已经增加了。
但是有时候,branch也会跳转的很远,远远超出16比特所能表示的地址范围。汇编器采用以下方法来解决这个问题:插入一条unconditional jump指令,用于跳转到目标地址,同时修改条件跳转指令,使其根据条件来选择是否跳过这个unconditional jump指令。
例如:beq $s0, $s1, L1
修改后为: bne $s0, $s1, L2
j L1
L2: