我刚刚开始学习MIPS,我很难理解跳转和分支指令的范围。我知道如何"远" PC可以跳转和分支,但我不知道原因。
如果PC
的当前值为0x00000000
,则有2个具体问题是否可以对随机地址执行1次JUMP?如果PC
的当前值为0x00000600
,是否可以对随机地址执行1 BRANCH?
答案 0 :(得分:8)
MIPS处理器使用固定大小的指令,其中每个指令字都是字(即4字节== 32位)。因此,只有这么多信息可以塞进这4个字节。
J
和JAL
指令使用32位中的6位来指定操作码。这留下26位来指定目标地址。目标地址不是直接在指令中指定的(没有足够的位) - 相反,会发生什么:
J
/ {{之后的指令地址的4个最高有效位组合1}}形成一个32位地址。这使得可以跳转到跳转指令所在的相同256MB范围(2 ^ 28)内的任何指令(或者如果启用了延迟分支;对于与指令相同的256MB范围内的任何指令在延迟槽中。)
对于分支指令,有16位可用于指定目标地址。这些存储为相对于分支指令之后的指令的有符号偏移(再次应用两位移位,因为不需要存储我们知道将始终为0的内容)。因此,在恢复2个最低有效位之后的实际偏移是18位,然后将其符号扩展为32位并且添加到分支指令之后的指令的地址。这使得可以在分支指令内分支到+/- 128kB。
考虑在地址0x00400024处加载的以下代码:
JAL
main:
j foo
nop
foo:
b main
nop
指令编码为j foo
。 26个最低有效位具有值0x0810000b
,其在向左移位2位后变为0x10000b
。 0x40002c
后面的指令地址的4个最高有效位为零,因此目标地址变为j
,等于(0 << 28) | 0x40002c
,恰好是0x40002c
的地址}。
foo
指令编码为b main
。 16个最低有效位具有值0x0401fffd
,其在向左移位2位后变为0xfffd
。将该值扩展到32位会给我们0x3fff4
。当将其添加到0xfffffff4
之后的指令地址时,我们得到b
,其中(当被截断为32位时)等于0x400030 + 0xfffffff4
,这恰好是{{1}的地址}}
如果要跳转到某个任意地址,请将地址加载到寄存器中,然后使用0x400024
或main
指令跳转。