【发布时间】:2014-02-08 13:51:27
【问题描述】:
我是汇编编程的初学者,想知道单个 EAX 通用寄存器可以容纳多少和多少。作为初学者,似乎每个 eax、ebx 等只有一个。注册。
【问题讨论】:
标签: assembly x86 cpu-registers
我是汇编编程的初学者,想知道单个 EAX 通用寄存器可以容纳多少和多少。作为初学者,似乎每个 eax、ebx 等只有一个。注册。
【问题讨论】:
标签: assembly x86 cpu-registers
在任何现代处理器中,每个线程只有一个 EAX。
所有其他架构寄存器也是如此。虽然您可以说,例如,有 8 个 MMX 寄存器,但这意味着只有一个 MM0、MM1、MM2 等...直到MM7.
【讨论】:
这些是逻辑寄存器名称。您假设每个正在运行的线程在程序中的任何给定点都有一个有效的 RAX 值是正确的(顺便说一下 - 使用超线程这意味着每个内核两个),但实际上现代硬件不包含单个值而是多个值.
现代的无序 CPU 将尝试根据源准备情况执行指令,因此对于下一个程序,例如:
mov rax, 1 ; #1
add rax, 2 ; #2
mov rax, 3 ; #3
add rax, 4 ; #4
CPU 可以在指令 #1 和 #3 被解码后立即执行它们,因为它们不需要满足任何依赖关系(并且运行 rax 中的旧值)。此外,指令#2 可以在之后立即并行执行,因为每个指令仅依赖于前面的指令。但是,为了在硬件中实现这一点,您需要能够将结果保存在某个临时寄存器中——因为他们提出了register renaming——而不是调用每个操作的结果rax,每条指令都会分配一个新的具有一些唯一 ID 的物理寄存器,并更新一些全局表(通常称为 RAT - 寄存器别名表),rax 现在由物理寄存器 #37 或其他表示。
重要的是必须使用正确的版本来维护源代码,因此它们也会同时被重命名。指令#2 不会使用rax,而是使用inst #1 的目的地。 Inst #4 将同样使用 inst #3 的结果。如果您接受重命名是按顺序完成的,并且别名已正确更新,则很容易看出从逻辑寄存器名称到物理寄存器名称的每次转换都保持正确的程序顺序。
因此,虽然对于流水线中的每条有效指令,您都有一个“正确的”rax 寄存器,这不一定是同一个物理寄存器。从某种意义上说,您可以说您有多个不同的逻辑寄存器副本,每个副本仅在下一次写入相同的逻辑名称之前有效。
【讨论】: