【问题标题】:Are registers real? Do they exist in CPU physically? [closed]寄存器是真的吗?它们物理上是否存在于 CPU 中? [关闭]
【发布时间】:2021-08-17 18:12:30
【问题描述】:

我开始学习 x86_64 汇编,我注意到的一件事是 rdi、rbp、rax、rbx 等寄存器的使用。它们是否存在于 CPU 中,或者这是汇编程序使用的某种抽象机制?

例如,如果我这样做

mov       rax, 60

这是否在硬件中找到具有此分配名称的寄存器?

【问题讨论】:

  • 是的,它们确实存在。当然,它们上面没有印有微小标签 :D 但是,现代 cpu 在物理上具有更大的寄存器文件,并且 cpu 将可见的架构寄存器映射到对程序员透明的寄存器文件。您通常不必处理它。
  • 物理寄存器是物理存在的。虚拟寄存器没有。 显然。 这个问题真的不是编程问题,也不属于 Stack Overflow。在 superuser.com 上可能是合适的。参见例如superuser.com/questions/695475/…
  • 更多的寄存器意味着更多的指令或不同的指令集。也明白 x86 是微编码的......许多/大多数架构不是。
  • 如果逻辑中的某处没有寄存器,处理器将如何工作?
  • 没有更多直接在汇编语言中可用的寄存器的原因与汇编语言的编码方式有关。指令中只有 3 位用于对寄存器进行编码。 64 位扩展增加了一位,允许 16 个寄存器。 AVX 编码为某些指令增加了一位,允许 32 种特定类型的向量寄存器。

标签: assembly cpu-architecture cpu-registers


【解决方案1】:

CPU 硬件无法通过 name 找到寄存器,这取决于汇编器将诸如 rax 之类的名称转换为 3 位或 4 位寄存器数字在机器代码中。(并且寄存器名称隐含的操作数大小也通过操作码和(缺少)前缀进行编码)。

例如add ecx, edx 集合到 01 d1Opcode 01 is add r/m32, r。第 2 个字节,ModRM 0xd1 = 0b0b11010001,对操作数进行编码:高 2 位 (11) 是寻址模式,普通寄存器,而不是内存(在这种情况下是 dest,因为它是 01 add r/m32, r 而不是 03 add r32, r/m32)。
中间 3 位是 /r 字段,010 = 2 是 edx 的寄存器号。
低3位为r/m字段,001为ECX的寄存器号。
(编号为 EAX、ECX、EDX、EBX ......,可能是因为 8086 是 designed for asm source compatibility with 8080 - 即在每条指令的基础上“移植”足够简单,机器可以自动完成。)

这是 CPU 实际解码的内容,以及它用来“寻址”其内部寄存器的内容。没有register renaming 的简单有序CPU 可以直接将这些数字用作实现寄存器文件的SRAM 中的地址。 (特别是如果它是像 MIPS 或 ARM 这样的 RISC。x86 很复杂,因为您可以使用具有不同宽度的相同寄存器编号,并且您可以将 AH 和 AL 之类的部分寄存器映射到 AX 的一半上。但这仍然只是一个问题将寄存器编号映射到 SRAM 中的位置,如果您没有进行寄存器重命名。)


对于 x86-64,寄存器编号始终为 4 位,但有时前导零是隐含的,例如在没有 REX 前缀的指令中,例如 mov eax, 60。寄存器编号位于该特殊编码的操作码的低 3 位中。

在物理上,现代 CPU 使用物理寄存器文件和寄存器重命名表 (RAT) 来实现架构寄存器。因此他们可以在多个时间点跟踪 RAX 的价值。例如mov eax, 60 / push rax / mov eax, 12345 / push rax 可以同时运行两个 mov 指令,写入单独的物理寄存器。但仍然要整理出push 应该从哪一个读取。


如果是这样,我想知道为什么 x86_64 架构中只有 16 个寄存器...

为 x86 竞争的高性能用例而设计的新 ISA很可能有 32 个整数寄存器。但是将其硬塞到 x86 机器代码中(就像 AVX-512 对矢量 reg 所做的那样),不值得代码大小的成本。

x86-64 是从 1979 年设计的 16 位 8086 演变而来的。如果现在以现代晶体管预算重新开始,当时做出的许多设计选择都不是您会做出的选择。 (而不是针对 8 位 8080 的 asm 源代码级兼容性)。

更多的体系结构寄存器在每个操作数的机器代码中花费更多位。更多的物理寄存器只是意味着更多的乱序执行能力来处理更多的寄存器重命名。 (物理寄存器编号是内部细节。)This article 测量实际的无序窗口大小以隐藏缓存未命中延迟,并将其与已知的 ROB 和 PRF 大小进行比较——在某些情况下,CPU 会用完物理寄存器来重命名到,在它填充 ROB 之前,针对所选的填充指令组合。


,更多的寄存器不是意味着更高的性能吗?

更多的架构寄存器通常确实有助于提高性能,但收益会递减。 16 与 8 相比避免了大量的存储/重新加载工作,但增加到 32 只会节省更多的存储/重新加载工作; 16 通常足以让编译器将他们想要的所有内容保存在寄存器中。

AMD 设法将其扩展到 16 个寄存器(从 8 个增加)这一事实已经是一项重大改进。是的,32 个整数 reg 有时会好一些,但如果不重新设计机器代码格式或使用更长的前缀(如 AVX-512 的 4 字节 EVEX 前缀,它允许 32 个 SIMD 寄存器,x/y /zmm0..31 用于 AVX-512 指令。)

另见:

相关问答:

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-17
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
  • 1970-01-01
  • 2014-05-18
  • 1970-01-01
相关资源
最近更新 更多