提问者:小点点

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


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

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

共2个答案

匿名用户

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

我假设你所说的“未命名寄存器”是这样的溢出值。除了你问题中列出的寄存器之外,最近的x86-64架构还提供MMX、SSE、AVX寄存器用于存储和一些操作,从而增加了寄存器的数量。不过,注意不要丢弃非易失性寄存器,即检查机器和操作系统的调用约定。

匿名用户

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

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

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

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

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

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

如果你给出更多关于你正在尝试做什么的细节,你可能会得到一个更好的答案。如果你试图模拟一个x86_64上有32个寄存器的处理器,那么你不需要寄存器的1对1映射。你正在模拟的平台的ABI将告诉你统计上可能发生的事情,因为过程最有可能被使用,并且它们对每个平台都有一个明确定义的(尽管每个CPUOS不同)约定。此外,对于大多数这样的项目,请考虑C或C。除了移植的困难之外,用汇编编写它不会有任何好处。