我刚开始学习MIPS,在理解跳转和分支指令的范围时遇到了麻烦。我知道PC跳跃和分支的“距离”是有限制的,但我不明白为什么。
还有两个具体的问题,如果PC
的当前值是0x00000000
,是否可以跳转到随机地址?如果PC
的当前值为0x00000600
,是否可以对随机地址执行1次分支?
发布于 2016-04-06 14:23:34
MIPS处理器使用固定大小的指令,其中每个指令字是一个字(即4字节== 32位)。所以这4个字节中只能塞入这么多的信息。
J
和JAL
指令使用32位中的6位来指定操作码。这样就剩下26位来指定目标地址。然而,目标地址并不是直接在指令中指定的(没有足够的位)-相反,发生的情况是这样的:
J
/JAL
之后的指令地址的4个最高有效位相结合以形成32位地址。这使得可以跳转到跳转指令所在的相同256MB范围(2^28)内的任何指令(或者,如果启用了延迟分支;则跳转到与延迟槽中的指令相同的256MB范围内的任何指令)。
对于分支指令,有16位可用于指定目标地址。这些被存储为相对于分支指令后面的指令的带符号偏移量(同样应用了两位移位,因为没有必要存储我们知道总是为0的东西)。因此,恢复2个最低有效位后的实际偏移量是18位,然后将其符号扩展到32位,并添加到分支指令后面的指令地址。这使得可以在分支指令内分支到+/-128kB。
考虑以下加载地址为0x00400024的代码:
main:
j foo
nop
foo:
b main
nop
j foo
指令被编码为0x0810000b
。26个最低有效位具有值0x10000b
,该值在向左移位2位之后变为0x40002c
。j
之后的指令地址的4个最高有效位为0,因此目标地址变为(0 << 28) | 0x40002c
,它等于0x40002c
,而0x40002c
恰好是foo
的地址。
b main
指令被编码为0x0401fffd
。16个最低有效位的值为0xfffd
,向左移位2位后变为0x3fff4
。Sign-将其扩展到32位,得到0xfffffff4
。当把它加到b
后面的指令的地址上时,我们得到了0x400030 + 0xfffffff4
,它(当截断到32位时)等于0x400024
,这恰好是main
的地址。
如果您想跳转到某个任意地址,请将该地址加载到一个寄存器中,并使用jr
或jalr
指令进行跳转。
https://stackoverflow.com/questions/36442586
复制相似问题