MIPS跳转和分支指令范围 [英] MIPS jump and branch instructions range

查看:1166
本文介绍了MIPS跳转和分支指令范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始学习MIPS,但在理解跳转和分支指令的范围时遇到了麻烦.我知道PC在多远的范围内可以跳跃和分支,但我不知道为什么.

I just started learning MIPS and I am having troubles understanding the ranges of jump and branch instructions. I know that there are limits on how "far" PC can jump and branch, but I don't get the reason why.

还有2个具体问题,如果PC的当前值为0x00000000,是否可以对随机地址做1个JUMP?如果PC的当前值为0x00000600,是否可以对随机地址进行1个分支?

And 2 specific questions, if current value of the PC is 0x00000000, is it possible to do 1 JUMP to a random address? if current value of the PC is 0x00000600, is it possible to do 1 BRANCH to a random address?

推荐答案

MIPS处理器使用固定大小的指令,其中每个指令字都是一个 word (即4个字节== 32位).因此,只有太多信息可以塞入这4个字节中.

MIPS processors uses fixed-sized size instructions, where each instruction word is, well, a word (i.e. 4 bytes == 32 bits). So there's only so much information that can be crammed into those 4 bytes.

JJAL指令使用32位中的6位来指定操作码.这留下了26位来指定目标地址.不过,目标地址并未在指令中直接指定(没有足够的位用于此操作)-相反,会发生以下情况:

The J and JAL instructions use 6 of the 32 bits to specify the opcode. This leaves 26 bits to specify the target address. The target address isn't specified directly in the instruction though (there aren't enough bits for that) - instead, what happens is this:

  • 目标地址的低28位右移2位,然后将26个最低有效位存储在指令字中.由于所有指令都必须按字对齐,因此我们移出的两位始终为零,因此我们不会丢失任何无法重新创建的信息.
  • 发生跳转时,将这26位左移2位以得到原始的28位,然后将它们与J/JAL之后的指令地址的4个最高有效位组合到形成一个32位地址.
  • The low 28 bits of the target address are shifted right 2 bits, and then the 26 least significant bits are stored in the instruction word. Since all instructions must be word-aligned the two bits that we shifted out will always be zeroes, so we don't lose any information that we can't recreate.
  • When the jump occurs, those 26 bits are shifted left 2 bits to get the original 28 bits, and then they are combined with the 4 most significant bits of the address of the instruction following the J/JAL to form a 32-bit address.

这使得可以跳转到跳转指令所在的相同256MB范围(2 ^ 28)中的任何指令(或者如果启用了延迟分支;则跳转到与该指令相同的256MB范围中的任何指令)在延迟插槽中.

This makes it possible to jump to any instruction in the same 256MB-range (2^28) that the jump instruction is located in (or if delayed branching is enabled; to any instruction in the same 256MB-range as the instruction in the delay slot).

对于分支指令,有16位可用于指定目标地址.它们存储为相对于分支指令之后的指令的有符号偏移量(再次应用了两位移位,因为不必存储我们知道的总为0的值).因此,恢复2个最低有效位后的实际偏移为18位,然后将其符号扩展为32位,并在分支指令之后添加到该指令的地址中.这样就可以在分支指令内分支到+/- 128kB.

For the branch instructions there are 16 bits available to specify the target address. These are stored as signed offsets relative to the instruction following the branch instruction (again with two bits of shifting applied, because it's unnecessary to store something that we know will always be 0). So the actual offset after restoring the 2 least significant bits is 18 bits, which then is sign-extended to 32 bits and added to the address of the instruction following the branch instruction. This makes is possible to branch to +/-128kB within the branch instruction.

请考虑以下在地址0x00400024处加载的代码:

Consider the following code loaded at address 0x00400024:

main:
j foo
nop
foo:
b main
nop

j foo指令被编码为0x0810000b. 26个最低有效位的值为0x10000b,向左移动2位后为0x40002c. j之后的指令地址的4个最高有效位为零,因此目标地址变为(0 << 28) | 0x40002c,等于0x40002c,恰好是foo的地址.

The j foo instruction is encoded as 0x0810000b. The 26 least significant bits have the value 0x10000b, which after shifting 2 bits to the left become 0x40002c. The 4 most significant bits of the address of the instruction following j are zero, so the target address becomes (0 << 28) | 0x40002c, which equals 0x40002c, which happens to be the address of foo.

b main指令被编码为0x0401fffd. 16个最低有效位的值为0xfffd,向左移动2位后为0x3fff4.将其符号扩展为32位可得到0xfffffff4.将其添加到b之后的指令的地址中时,我们得到0x400030 + 0xfffffff4,它(被截断为32位时)等于0x400024,恰好是main的地址.

The b main instruction is encoded as 0x0401fffd. The 16 least significant bits have the value 0xfffd, which after shifting 2 bits to the left becomes 0x3fff4. Sign-extending that to 32 bits gives us 0xfffffff4. And when adding that to the address of the instruction following the b we get 0x400030 + 0xfffffff4, which (when truncated to 32 bits) equals 0x400024, which happens to be the address of main.

如果要跳转到某个任意地址,请将地址加载到寄存器中,并使用jrjalr指令跳转.

If you want to jump to some arbitrary address, load the address into a register and use the jr or jalr instruction to jump.

这篇关于MIPS跳转和分支指令范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆