如果我在 rbx 寄存器中有一个地址并使用类似的指令
mov rax, [rbx+1]
rbx+1 是在运行时在硬件中计算的吗?如果是的话,是否使用了一些寄存器或者是否有专用的硬件?
我想执行相同的指令,但使用符号而不是像这样的寄存器
string: db "I'm lost", 0
mov rax, [string+1]
允许在编译时完成计算,因为它已经在内存中保留了一个位置。而 rbx 在运行时之前会更加可变且未知。
所有 CPU,甚至是最初的 8086,都有一些与架构寄存器分开的临时缓冲区。 8086 使用主 ALU 进行地址数学运算,因此
add ax, [bx + si + 1]
需要使用该临时存储;地址数学不会影响 BX 或 RBX 寄存器中软件可见的值。
像 8086 这样的旧 CPU 通过运行一系列内部微代码指令来处理甚至简单的 x86 指令。现代 CPU 将像
mov eax, [rbx+1]
这样的指令解码为加载执行单元的单个微操作 (uop)。 (它们在管道阶段之间仍然有缓冲,甚至还有一些临时寄存器供 xchg eax, ecx
等指令使用;在 Intel 上,这是一个 3-uop 指令,类似于 mov internal_tmp, ecx
/ mov ecx, eax
/ mov eax, internal_tmp
。)
现代 CPU 具有专用地址生成单元 (AGU),作为加载和存储地址执行单元的一部分,与 ALU 执行单元分开。 有关详细信息,请参阅 https://realworldtech.com/sandy-bridge/10框图。
相关:
[rbx+1]
值与 [rbx]
位于同一页面,如果 rbx
值从另一个负载转发。通过让 TLB 访问更快开始,这将指针追踪(例如链表和二叉树)的加载使用延迟减少到 4 个周期,而通常为 5 个周期。请注意,LEA 是一种单独的动物;它的结果被写入寄存器,不用于加载或存储,因此现代 CPU 将其作为移位加法指令在 ALU 执行单元上运行。 (一些支持它的 ALU 不支持移位部分,或者只支持一个添加,具体取决于 CPU 型号。请参阅在不是地址/指针的值上使用 LEA? - 尽管无论是否整数值是否出现在有效指针上。