跳转和链接寄存器MIPS [英] Jump and Link Register MIPS

查看:160
本文介绍了跳转和链接寄存器MIPS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究MIPS指令,此问题使我有些困惑,因为MIPS文档似乎在说与提供的答案有所不同的内容.这是问题和答案:

I am studying MIPS instructions and this problem is confusing me a bit because the MIPS documentation seems to be saying something different from the answer provided. Here is the problem and answer:

该指令在位置0x5000中引用和/或更改了哪些寄存器?

What registers are referred to and/or changed in this instruction at location 0x5000?

0x5000 : 0x0140F809

answer:

Opcode = 0x00,R type,Function = 0x09(jalr),Rs = 10($t2)

Opcode=0x00, R type, Function=0x09 (jalr), Rs=10($t2)

跳转到$t2

0x5004放入$ra

但是,从文档中可以看出,它在寄存器31($ra)中放置了PC +4.因此,由于指令是在地址0x5000上执行的,因此PC应该为0x5004,对吗?那么JALR指令不应该将0x5004 + 4或0x5008放入PC而不是0x5004吗?

However, from the documentation, it says that in register 31 ($ra), it puts the PC + 4. So since the instruction is executing at address 0x5000, the PC should be 0x5004 right? So shouldn't the JALR instruction put 0x5004 + 4, or 0x5008, into the PC and not 0x5004?

对我来说,应该跳回到0x5004是有意义的,因为从技术上讲,这是跳转之后的下一条指令,但是文档明确指出R [31] = PC + 4,这使我有些困惑,这会使我感到困惑是x5008.谢谢!

To me it makes sense that it should jump back to 0x5004 since that is technically the next instruction after the jump, but the documentation explicitly says R[31] = PC + 4 so it is confusing me a little bit, which would be x5008. Thanks!

推荐答案

您需要考虑的是分支延迟槽.

首先让我们处理它们关闭的情况.这是spimmars之类的模拟器的默认设置.事情很简单:

First let's handle the case where they're off. This is the default for simulators like spim and mars. Things are simple:

5000: jalr $10                      # (1) $31 will have 5004
5004: nop                           # (2) this executed upon return

这是大多数体系结构的工作方式.

This is the way most architectures work.

但是,mips具有[上述]分支延迟时隙.

But, mips has [the aforementioned] branch delay slots.

如果(在模拟器中)或实际硬件中启用了延迟,则在每转移控制指令(例如,branch,jump,jal,jalr)之后,延迟槽中就会出现一条指令,是无条件执行的,而之前实际上是在分支[或不是]的情况下执行的:

If the delays are enabled [in simulators] or real hardware, after every transfer of control instruction (e.g. branch, jump, jal, jalr) is a single instruction that follows in the delay slot that is unconditionally executed before the branch is actually taken [or not]:

5000: jalr $10                      # (1) $31 will have 5008
5004: nop                           # (2) this executed _before_ branch taken
5008: nop                           # (3) this executed upon return

因此,有效执行顺序实际上是(2),(1),(3).

So, the effective execution order is actually (2), (1), (3).

通常情况下,您需要执行以下三个步骤:

In the general case, you have a three step sequence:

5000: beqz $10,foobar               # (1) conditional branch to foobar
5004: nop                           # (2) executed _before_ branch taken
5008: nop                           # (3) executed _after_ if branch _not_ taken

再次,有效的执行顺序将为(2),(1).然后,执行foobar的第一条指令[如果分支是 take ]或执行5008(3)的指令,如果分支是 not 拍摄.

Once again, the effective execution order will be (2), (1). Then, either the first instruction of foobar is executed [if the branch was taken] or the instruction at 5008 (3) will be executed if the branch is not taken.

好的,您可能会问为什么?

在早期的MIPS芯片中,指令是预取的.例如,周期N + 1的指令是在周期N(一个周期 delay )中预取(并可能已预解码)的.

In early MIPS chips, instructions were prefetched. For example, the instruction for cycle N+1 was prefetched [and possibly predecoded] in cycle N (a one cycle delay).

因此,在循环N上,指令 execution 单元正在执行在循环N-1中获取的指令(例如5000),指令 prefetch 单元正在获取下一个指令指令(在5004).它们与一个周期的延迟重叠.在周期N + 1中,执行单元正在执行预取指令(在5004),而预取单元正在预取下一条指令(在5008).

So, on cycle N, the instruction execution unit is executing the instruction fetched in cycle N-1 (e.g. 5000), the instruction prefetch unit is fetching the next instruction (at 5004). They overlap with the one cycle delay. In cycle N+1, the execution unit is executing the prefetched instruction (at 5004) and the prefetch unit is prefetching the next instruction (at 5008).

这很好,直到遇到有条件的控制指令转移为止.

This works great until a conditional transfer of control instruction is encountered.

没有延迟时隙,处理器将不得不停顿,并且在与执行分支相同的周期中预取了分支之后的指令将被浪费.通过执行延迟插槽,通常可以在插槽中填充一些有用的东西,因此不必浪费预取信息.

Without the delay slot, the processor would have to stall, and the instruction after the branch that got prefetched on the same cycle as the branch was executed would be wasted. With the delay slot execution, you can usually populate the slot with something useful, so the prefetch needn't be wasted.

但是,这确实使事情变得更加复杂.

But, it does makes things a bit more complicated.

这篇关于跳转和链接寄存器MIPS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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