如果您要问为什么ISA首先不提供它,那只是设计选择.通过提供更少或更简单的寻址模式,您将获得以下优势:需要较少的空间来编码一组更有限的可能性,因此您可以节省编码空间,以存放更多的操作码,较短的指令等.硬件可以更简单或更快速.例如,在地址计算中允许两个寄存器可能会导致:在寄存器文件中需要额外的读取端口.寄存器文件和AGU之间的附加连接,以在那里获得两个寄存器的值.需要进行全宽度(32或64位)加法运算,而不是简单的地址端+ 16位加法偏移.如果您仍然希望使用2寄存器地址支持立即数偏移量,则需要具有三输入ALU(如果您不希望使用它们,则它们的用处不大).指令解码和地址生成的额外复杂性,因为您可能需要支持两条截然不同的路径来生成地址.当然,所有这些权衡取舍在某些情况下都可以很好地得到回报,这些情况可以通过使用较小或较快的代码来充分利用2-reg地址,但是受RISC哲学启发的原始设计却没有做到这一点.包括它.正如彼得指出的那样,在注释中,新的寻址模式在某些情况下随后添加了,尽管显然不是用于加载或存储的通用2-reg寻址模式.那里有些二分法错误.从硬件可以当然支持这一意义上说,这当然不是硬件限制,即使在设计MIPS时也是如此.似乎暗示着某些现有硬件具有该限制,因此MIPS ISA以某种方式继承了它.我会怀疑这是另一回事:ISA是根据对硬件实现可能性的分析来定义的,然后由于不需要MIPS硬件,因此成为了硬件简化支持MIPS ISA之外的任何功能. 例如,支持需要从3个寄存器中读取的存储指令. 当然,值得问一下这样的伪指令是否是一个好主意:它可能会扩展为将两个寄存器加到一个临时寄存器中,然后再加上一个lw结果.始终存在将太多"工作隐藏起来的危险.由于这部分掩盖了将1:1映射到硬件负载的实际负载与在幕后进行额外算术的版本之间的差异,因此很容易想象这可能导致最佳决策.以经典示例为例,该示例在循环中线性访问两个元素大小相等的数组.使用2寄存器寻址时,很自然地将此循环写为两个2寄存器访问(每个寄存器具有不同的基址寄存器和公共偏移寄存器).偏移量维护的唯一开销"是单个偏移量增量.这掩盖了这样一个事实,即内部需要两个隐藏的添加来支持寻址模式:直接增加每个基数而不使用偏移量会更好.此外,清除开销后,您可以看到展开循环并使用立即偏移量可以进一步减少开销. I'm curious as to why we are not allowed to use registers as offsets in MIPS. I know that you can't use registers as offsets like this: lw $t3, $t1($t4); I'm just curious as to why that is the case.Is it a hardware restriction? Or simply just part of the ISA? 解决方案 I'm not sure if you mean "why does MIPS assembly not permit you to write it this form" or "why does the underlying ISA not offer this form".If it's the former, then the answer is that the base ISA doesn't have any machine instructions that offers that functionality, and apparently the designers didn't decide to offer any pseudo-instruction that would implement that behind the scenes.If you're asking why the ISA doesn't offer it in the first place, it's just a design choice. By offering fewer or simpler addressing modes, you get the following advantages:Less room is needed to encode a more limited set of possibilities, so you save encoding space for more opcodes, shorter instructions, etc.The hardware can be simpler, or faster. For example, allowing two registers in address calculation may result in:The need for an additional read port in the register file.Additional connections between the register file and the AGU to get both registers values there.The need to do a full width (32 or 64 bit) addition rather than a simpler address-side + 16 bit-addition for the offset.The need to have a three-input ALU if you want to still want to support immediate offsets with the 2-register addresses (and they are less useful if you don't).Additional complexity in instruction decoding and address-generation since you may need to support two quite different paths for address generation.Of course, all of those trade-offs may very well pay off in some contexts that could make good use of 2-reg addressing with smaller or faster code, but the original design which was heavily inspired by the RISC philosophy didn't include it. As Peter points out in the comments, new addressing modes have been subsequently added for some cases, although apparently not a general 2-reg addressing mode for load or store.There's a bit of a false dichotomy there. Certainly it's not a hardware restriction in the sense that hardware could certainly support this, even when MIPS was designed. It sort of seems to imply that some existing hardware had that restriction and so the MIPS ISA somehow inherited it. I would suspect it was much the other way around: the ISA was defined this way, based on analysis of how likely hardware would be implemented, and then it became a hardware simplification since MIPS hardware doesn't need to support anything outside of what's in the MIPS ISA. E.g., to support store instructions which would need to read from 3 registers. It's certainly worth asking whether such a pseudo-instruction is a good idea or not: it would probably expand to an add of the two registers to a temporary register and then a lw with the result. There is always a danger that this hides "too much" work. Since this partly glosses over the difference between a true load that maps 1:1 to a hardware load, and the version that is doing extra arithmetic behind the covers, it is easy to imagine it might lead to sup-optimal decisions.Take the classic example of linearly accessing two arrays of equal element size in a loop. With 2-reg addressing, it is natural to write this loop as two 2-reg accesses (each with a different base register and a common offset register). The only "overhead" for the offset maintenance is the single offset increment. This hides the fact that internally there are two hidden adds required to support the addressing mode: it would have simply been better to increment each base directly and not use the offset. Furthermore, once the overhead is clear, you can see that unrolling the loop and using immediate offsets can further reduce the overhead. 这篇关于使用寄存器作为偏移量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-11 03:17