索引寻址模式和隐含寻址模式

索引寻址模式通常用于访问数组,因为数组是连续存储的。我们有一个索引寄存器,它在每次迭代时都会增加,当它被添加到基地址时,会给出数组元素地址。 我不明白这种寻址模式的实际需要。为什么我们不能直接寻址?我们有基地址,每次访问时我们都可以加1。为什么我们需要索引寻址模式,它具有索引寄存器的开销?索引寻址模式和隐含寻址模式

我不确定隐含寻址模式的指令格式。假设我们有一个INC AC指令。是指令中指定的AC地址还是有一个特殊的操作码,意思是“INC AC”,我们不包括AC(累加器)的地址?

回答:

我不明白这种寻址模式的实际需要。为什么我们不能直接寻址?

你可以; MIPS只有一种寻址模式,编译器仍然可以为它生成代码。但有时它必须使用额外的移位+ add指令来计算一个地址(如果它不只是循环通过一个数组)。

寻址模式的要点是保存指令和保存寄存器,特别是在2个操作数指令集等的x86,其中add eax, ecx覆盖eax,其结果(eax += ecx),不像MIPS或其它3-指令的ISA,其中addu $t2, $t1, $t0确实t2 = t1 + t0 。在x86上,这需要一个副本(mov)和一个add。 (或者在这种特殊情况下,x86可以使用与内存操作数相同的指令编码进行复制和添加(和移位)。)

考虑一个直方图问题:以不可预知的顺序生成数组索引,并且必须索引一个数组。在x86-64上,add dword [rbx + rdi*4], 1将使用单个4字节指令在内存中增加一个32位计数器,该指令仅解码为2个uops,以便前端在现代Intel CPU上发布到无序内核。 (http://agner.org/optimize/)。 (rbx是基址寄存器,rdi是缩放索引)。有规模指数是非常强大的; x86 16位寻址模式支持2个寄存器,但不支持缩放索引。

虽然MIPS32确实为地址计算添加了缩放指令,但传统MIPS只有单独的移位和添加指令。这可以节省一条指令。作为一个加载存储机器,加载和存储总是必须是单独的指令(不同于在x86上,加载解码为微加载+添加和存储,请参阅INC instruction vs ADD 1: Does it matter?)。

ARM可能是MIPS的一个更好的比较:它也是一个加载存储RISC机器。但它确实有多种寻址模式,包括使用桶形移位器的缩放索引。因此,您不需要为每个数组索引单独移位/添加,而是使用LDR R0, [R1, R2, LSL #2],add r0, r0, #1/str以及相同的寻址模式。

通常在循环数组时,最好只增加x86上的指针。但它也是一个使用索引的选项,特别是对于使用相同索引的多个数组的循环,如C[i] = A[i] + B[i]。但索引寻址模式有时可能为slightly less efficient in hardware,因此,当编译器展开循环时,它通常应该使用指针,即使它必须单独增加所有3个指针而不是一个索引。


指令集设计的关键是不仅是图灵完成,这是使高效代码,获取与更少的时钟周期和/或更小的代码尺寸,或给程序员更多的工作要做瞄准这些目标中的任何一个的选项。

计算机可编程的最低阈值非常低,请参阅各种One instruction set computer体系结构。 (没有实现,只是设计在纸上,以表明可以用除了分支和分支之外的指令编写程序,并在指令中编码内存操作数,这是可以写入程序的

这里有在易于解码(尤其是并行解码)和紧凑的x86之间进行权衡,x86是非常可怕的,因为它是作为一系列扩展发展而来的,往往没有大量的计划为未来的扩展留下空间。决定,请参阅Agner Fog的博客,了解关于为高性能CPU设计ISA的有趣讨论,这些讨论将x86的最佳特性(大量工作与一条指令,例如内存操作数作为ALU指令的一部分)与最佳特性RISC(易于解码,大量寄存器):Proposal for an ideal extensible instruction set。

还有一种折衷方法是在指令字中如何使用位,特别是在像大多数RISC一样的固定指令宽度的ISA中。不同的国际检索单位有不同的选

  • PowerPC使用大量的编码空间用于强大的位域指令,如rlwinm(左旋和遮罩位窗口)以及大量的操作码。 IDK如果通常不可发音且难以记忆的助记符与此相关...
  • ARM使用高4位来根据条件码预测执行任何指令。它使用更多的位为the barrel shifter(第二个源操作数可选地通过立即数或来自另一个寄存器的计数来移位或旋转)。
  • MIPS具有相对较大的立即操作数,基本上很简单。

x86 32/64位寻址模式使用可变长度编码,在有索引时使用额外的字节SIB(scale/index/base)字节,以及可选的disp8或disp32即时位移。 (例如add esi, [rax + rdx + 12340]需要2 + 1 + 4个字节来编码,对2个字节用于add esi, [rax]

86的16位寻址模式是有限得多,并且包以外的所有可选DISP8/disp16位移到MODR/M字节。


假设我们有一个指令INC交流。交流是在指令指定的地址或者是有一个特殊的操作码,这意味着“INC AC”,我们不包括AC地址(累加器)?

是的,某些ISA的某些指令的机器码格式包含隐式操作数。许多机器具有暗指使用特定寄存器作为堆栈指针的指令push/pop。例如,在x86-64的push rax中,RAX是一个明确的寄存器操作数(encoded in the low 3 bits of the one-byte opcode using the push r64 short form),而RSP是一个隐式操作数。

老的8位CPU通常有类似DECA的指令(减少累加器A)。即该寄存器有一个特定的操作码。这可能与具有DEC指令的操作码字节中的某些位指定哪个寄存器(与x86-64在x86-64之前的操作将short INC/DEC encodings改为REX前缀)相同:请注意64位中的“NE”(不可编码)模式列为dec r32)。但是如果没有规律的模式,那么它绝对可以被认为是一个隐式操作数。

有时候将事物划分为整齐的类别,所以不要太担心使用位操作码字节数是否为x86的隐式或显式。这是一种花费更多操作码空间的方式来保存常用指令的代码大小,同时仍允许使用不同的寄存器。

一些ISA只按照约定使用某个寄存器作为堆栈指针,没有任何隐含用途。 MIPS就是这样。

ARM32(在ARM中,不是Thumb模式)也在push/pop中使用显式操作数。它的push/pop助记符只是用于存储多次递减的别名,以前/ load-multiple increment-after(LDMIA/STMDB)来实现完全递减堆栈。 LDM/STM的ARM's docs解释了这一点,你可以用这些指令的一般情况来做什么,例如LDMDB递减指针,然后加载(与POP相反的方向)。

以上是 索引寻址模式和隐含寻址模式 的全部内容, 来源链接: utcz.com/qa/263181.html

回到顶部