assembly 为什么MIPS不能在寻址模式下使用两个寄存器?

ia2d9nvy  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(145)

我很好奇为什么我们不允许在MIPS中使用寄存器作为偏移量。我知道你 * 不能 * 像这样使用寄存器作为偏移量:我只是好奇为什么会这样。
这是硬件限制吗?还是只是伊萨的一部分?
PS:如果您正在寻找替代方法,请参见 * Load Word in MIPS, using register instead of immediate offset from another register * 或查看编译器输出的C函数,如int foo(int *arr, int idx){ return arr[idx]; }-https://godbolt.org/z/PhxG57ox1

k2arahey

k2arahey1#

我很好奇为什么不允许我们在MIPS中使用寄存器作为偏移量。
我不确定您的意思是“为什么MIPS程序集不允许您以这种形式编写它”还是“为什么底层伊萨不提供这种形式”。
如果是前者,那么答案是基本伊萨没有任何机器指令提供该功能,显然设计者没有决定提供任何pseudo-instruction来在幕后实现该功能。2
如果您问伊萨为什么不提供这种寻址模式,那只是一种设计选择。通过提供更少或更简单的寻址模式,您可以获得以下优势:

  • 对一组更有限的可能性进行编码所需的空间更少,因此您保存编码空间,用于更多的操作码、更短的指令等。
  • 硬件可以更简单或更快。例如,在地址计算中允许两个寄存器可能导致:
  • 寄存器file 1中需要额外的读取端口。
  • 寄存器文件和AGU之间的附加连接,用于获取两个寄存器的值。
  • 需要进行全宽度(32或64位)加法,而不是更简单的地址侧+16位加法。
  • 如果您仍希望支持2寄存器地址的立即数偏移量,则需要使用三输入ALU(如果不支持,则它们的用处不大)。
  • 由于可能需要支持两种完全不同的地址生成路径,因此指令解码和地址生成更加复杂。

当然,在某些情况下,所有这些权衡可能会得到很好的回报,可以很好地利用2-reg寻址和更小或更快的代码,但最初的设计,这是在RISC哲学的重大启发没有包括它。正如Peter在评论中指出,新的寻址模式 * 已经 * 随后被添加到某些情况下,虽然显然不是用于加载或存储的一般2-reg寻址模式。
这是硬件限制吗?还是只是伊萨的一部分?
这里有一点错误的二分法。当然,这不是一个硬件限制,因为硬件 * 肯定 * 可以支持这一点,即使在MIPS被设计的时候。这似乎暗示了一些现有的硬件有这个限制,所以MIPS伊萨以某种方式继承了它。我会怀疑它是相反的:伊萨是这样定义的,它基于对硬件实现可能性的分析,然后它变成了一种 * 硬件简化 *,因为MIPS硬件不需要支持MIPS ISA之外的任何东西。
1例如,支持需要从3个寄存器读取的存储指令。
[2]这样的伪指令是否是一个好主意,当然值得一问:它可能会扩展为将两个寄存器加到一个临时寄存器上,然后用lw来计算结果。这样做总是有隐藏“太多”工作的危险。由于这部分掩盖了1:1Map到硬件负载的真实负载和在掩盖后进行额外运算的版本之间的差异,很容易想象它可能会导致次优决策。
以在循环中线性访问两个元素大小相等的数组为例。对于2-reg寻址,很自然地将此循环写为两次2-reg访问(每一次访问都有不同的基址寄存器和公共的偏移量寄存器)。偏移量维护的唯一“开销”是单个偏移量增量。这隐藏了一个事实,即内部有两个隐藏的加法需要支持寻址模式:直接递增每个基址而不使用偏移量会更好。此外,一旦开销被清除,您可以看到展开循环并使用立即数偏移量可以进一步减少开销。

相关问题