【问题标题】:MIPS Jump instruction encoding: why left shifted, and why keep the high 4 bits of PC?MIPS跳转指令编码:为什么要左移,为什么要保留PC的高4位?
【发布时间】:2020-07-18 19:03:59
【问题描述】:

在跳转指令中,

  1. 为什么要将 26 位地址转换为 28 位?
  2. 为什么我们将 PC 中最左边的 4 位添加到 28 位中?

【问题讨论】:

标签: assembly mips cpu-architecture machine-code


【解决方案1】:

为什么要将 26 位地址转换为 28 位?

当我们将地址移动 2 位时,跳转指令的参数(地址)可以在 0...2^28-1 的范围内。

如果我们不移动地址,它只能在 0...2^26-1 范围内。

这意味着我们只能使用 1/4 的地址空间。

另一方面,不转移地址的明显好处并不是真正的好处:

不移动地址将允许使用不能被 4 整除的地址。但是,因为指令总是位于能被 4 整除的地址,所以跳转到不能被 4 整除的地址的指令是没有意义的。

顺便说一句:其他 CPU(例如 MC68000)确实使用 16 位“分支”(跳转)指令,其中低位始终必须为零 - 因此如果 CPU 将地址移动 1,则可以寻址更多内存.

为什么我们要把最左边的 4 位从 PC 加到 28 位上?

PC 寄存器为 32 位宽,跳转指令仅包含 26 位。所以我们必须从其他地方取 6 位:

PC 寄存器的低 2 位始终为零,所以我们仍然要考虑“左”4 位。

如果我们总是将左 4 位设置为零,我们只能跳转到位于前 256 MB 内存中的一些代码。

如果我们根本不修改 PC 的左 4 位,我们可以跳转到与跳转指令本身位于相同 256 兆字节范围内的一些代码。

让我们考虑一个for()while() 循环:

在这样的循环结束时,有一条跳转到循环开始的指令。

假设程序不一定位于前 256 MB 内存中。

更有可能:

循环开始与循环结束(跳转指令)在相同的 256 兆字节范围内,还是循环开始在前 256 兆字节内存内?

【讨论】:

  • 在这样的循环结束时有一个跳转指令到循环的开始。 通常你会使用条件分支作为循环分支,比如@987654323 @ 某物。 MIPS 条件分支是相对的,向 PC 添加偏移量。或者,如果您将 C 循环音译为底部带有无条件分支的 asm,您仍然可以通过使用始终为真的条件(如 bgez $zero, loop_top)来执行短程无条件相对分支。但可以肯定的是,作为一个例子,它可以工作,并且许多手写的 MIPS 代码确实使用j 用于此类分支。
  • 谢谢,第二个问题困扰了我很久
  • forwhile的例子很奇怪,跳转指令在最后,怎么能向后跳转到循环的开头呢?一定是相对跳跃。
  • @shino 实际上,循环结束时通常会有相对跳转。原因之一是不需要搬迁。但是,也可以使用J 指令。如果循环长于 32K 条指令,你甚至不得不使用 J 而不是 BGEZ,因为对于 BGEZ 来说,循环的起点太远了。
猜你喜欢
  • 2017-06-08
  • 1970-01-01
  • 2020-08-31
  • 2014-02-10
  • 2016-04-16
  • 2020-07-23
  • 1970-01-01
  • 2017-02-08
  • 1970-01-01
相关资源
最近更新 更多