x86-64 处理器中没有足够的寄存器

There aren't enough registers in x86-64 processor

我们在 x86-64 处理器中有 16 个通用寄存器: RAX、RCX、RDX、RBX、RSP、RBP、RSI、RDI、R9-15。 x86-64 处理器为我们提供了其他类型的寄存器。我的问题是:

  1. 我需要使用 32 个寄存器作为通用寄存器。可能吗。怎么样?
  2. 我听说 x86-64 处理器有更多的通用寄存器,但没有命名。只有 16 个命名寄存器。那么,这是真的吗?是否可以使用它们?

在任何给定时间,您不能使用比 CPU 提供的更多的寄存器;但是,您可以一个接一个地为多个值重复使用同一个寄存器。这称为 register allocation and register spilling,其中值使用 rSP 堆栈指针寄存器在 CPU 寄存器和程序堆栈之间移动。

我假设你所说的 "unnamed registers" 就是这样的溢出值。除了您问题中列出的寄存器之外,最近的 x86-64 架构还提供 MMX, SSE, AVX registers for storage and some operations, thus increasing your number of registers. Be careful not to trash non-volatile registers though, i.e. check the calling convention 您的机器和操作系统。

我需要使用32个寄存器作为通用寄存器。可能吗。怎么样?

不,架构只定义了 16 个,它们不是完全通用的。某些指令仅适用于某些寄存器。您可能想要做的是在堆栈(C 局部变量所在的位置)上的激活记录(数据结构)中定义您的状态,然后根据需要将这些值加载到寄存器中。如果我理解你想要做什么,我只能详细说明,但我建议你查看 OS(或 some OS 的 ABI,如果您没有使用 OS) 来查看进行过程调用时寄存器预期发生的情况。使用 ABI 来指导您的寄存器使用也将帮助您与更高级的语言(例如 C 或 C++)进行互操作。

我听说 x86-64 处理器有更多的通用寄存器,但它们没有命名。只有 16 个命名寄存器。那么,这是真的吗?是否可以使用它们?

其他通用寄存器用于乱序执行系统在不改变指令流的串行语义的情况下调度指令流中即将到来的指令的执行。这个过程称为"register renaming"。在一些芯片上,额外的寄存器根本不存在,因为这些芯片不执行乱序执行。额外的寄存器是 CPU 的实现细节,它们不能从 x86_64 指令集访问。其他架构通过提供 VLIW(超长指令字)指令集来避免乱序执行,该指令集使用编译器来调度指令,而不是让硬件来调度它们。安腾就是这样的架构。

生产Itanium时,VLIW架构已经失宠,所以他们称其为EPIC(Explicitly Parallel Instruction Computing)而不是VLIW,但它仍然是VLIW。 Itanium 有 128 个通用寄存器,这是因为预计您(C 或 C++ 编译器)将安排大量同时进行的操作(语义上)。每个指令包有 3 条指令(以及 3 条指令中的每条指令的谓词指示符)和一个指示符,指示符是否预期(语义上)同时执行以下包。它不必同时执行。您可以链接 27 条指令同时执行,但如果您使用低端 Itanium,它可能一次执行 3 条,如果您使用高端 Itanium,则可能一次执行 9 条,但结果在任一处理器上都是相同的,在执行以下指令之前,它只需要更长或更短的周期数。

正如我所说,VLIW 已经失宠,因为 C 和 C++ 编译器可以以乱序执行系统可以确定指令流的数据依赖性并执行类似工作的方式对指令进行排序调度,这也允许未来的处理器有更宽的执行流水线阶段,而不会将寄存器数量限制在 128 个。无论如何这就是理论。

如果您提供有关您尝试执行的操作的更多详细信息,您可能会得到更好的答案。如果您尝试在 x86_64 上模拟具有 32 个寄存器的处理器,则不需要寄存器的 1 对 1 映射。您正在模拟的平台的 ABI 会告诉您在统计上可能发生什么,因为最有可能使用程序,并且它们有一个明确定义的(尽管根据 CPU 和 OS 不同)约定每个平台。另外,对于大多数此类项目,请考虑使用 C 或 C++。全部用汇编写,你不会有任何收获,除了移植困难。