【问题标题】:What is the point of offset in mips lw and sw instructions?mips lw 和 sw 指令中的偏移点是什么?
【发布时间】:2021-10-31 01:09:00
【问题描述】:

我的老师刚刚讨论了这个话题,但我仍然想知道为什么要使用偏移量。是在某种前缀的帮助下对值进行分类吗?如果您能以简单的方式解释为什么在这些说明中使用偏移量,我将不胜感激。

【问题讨论】:

  • 因此您可以访问寄存器未直接指向的内容,而无需在单独的指令中添加偏移量。例如。你可能有一个指向结构的指针,你可以访问带有偏移量的字段。

标签: assembly mips cpu-architecture mips32 addressing-mode


【解决方案1】:

偏移量用于几种不同的场景。以下是一些示例:

  1. 许多算法自然会涉及A[i+1] 之类的表达式。编译器将计算 A+i,并使用偏移量 4 来获得 +1(假设 A 是一个 4 字节元素的数组)。

    在展开循环甚至只涉及A[i] 之后,展开的部分引入了A[i+1]A[i+2] 等的用法,其中偏移量很有用。

  2. 当我们访问基于堆栈的内存时,基址寄存器将是堆栈指针,寄存器$sp。这里的偏移量表示要访问哪个堆栈槽,对于访问本地基于堆栈的变量非常方便。

  3. 堆栈有一些隐藏的用法(对 C 程序员隐藏),其中包括保留 $s 寄存器值、返回地址寄存器值 $ra,以及可能在寄存器中传递的参数。这些也可以使用$sp 作为基址寄存器和适当的偏移量来访问正确的插槽。

    调用者(设置参数)和被调用者(访问它们)都将不适合寄存器的参数传递到堆栈上并使用$sp 作为基数和适当的偏移量进行访问。

  4. 可以使用两个指令序列访问全局变量,使用 lui 后跟 lwsw 以及适当的偏移量。 lui 指令形成高 16 位,lwsw 指令提供低 16 位。因此,可以形成一个 32 位的地址,以访问地址空间中任意位置的全局变量。

  5. 对象具有字段,并且使用指向对象的指针和对象内字段的偏移量来访问字段。因此,在 C 语言中,p->f1,其中f1 的偏移量为 8,将使用以 p 作为基址寄存器和 8 作为偏移量的加载或存储。 p->f2 将使用相同的 p 但不同的偏移量。

总而言之,在很多情况下,基数 + 非零常数是有用的。零常数也非常有用,正如您已经知道的 *p(简单取消引用)和 A[i](数组索引),因此 MIPS 选择仅提供一种寻址模式。

其他架构提供多种寻址模式,例如带偏移和不带偏移(以及其他)的取消引用,因此对于他们来说,您选择不带偏移而不是提供零偏移。然后您可以使用较短的指令,因为没有偏移编码(并且短指令有利于代码密度,这有利于指令缓存性能)。但是,要利用这一点,您需要一个可变长度的指令集和更多的编码,而 MIPS 选择反对这两种编码,以符合其 RISC 理念。

【讨论】:

  • MIPS 并不是唯一的,它只有一种寻址模式。其他几个经典 RISC ISA 是相同的,例如我认为是 SPARC。 (不出所料,RISC-V)。 PowerPC 的有趣之处在于具有一些缩放索引加载/存储指令。 Using a register as an offset 讨论了这样一个事实,即没有 2 个寄存器存储指令可以避免需要第 3 个寄存器文件读取端口。 (有趣的是,后来的 MIPS 修订版确实添加了索引 FP 加载/存储,但没有添加整数,可能是因为 FP 数学循环中的两个用例单独的 reg 文件)
  • 非常感谢您的详细解释
  • @Peter Cordes。感谢您提供额外的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
  • 2017-07-02
  • 2018-06-06
  • 2020-06-01
  • 2019-08-07
  • 1970-01-01
相关资源
最近更新 更多