32位和64位值共享相同的寄存器空间吗?
答
是,
您的代码:
mov rax,rdx
mov eax,edx
将执行以下操作。
rax <= rdx
high 32 bits of rax <= 0, low 32 bits of rax <= edx.
分配32位寄存器将使该寄存器的较高部分为零。
与此相反的:
mov rax,rdx : rax <= rdx
mov ax,dx : High 48 bits of rax is unchanged!, low 16 bits of rax <= dx
这同样适用于字节寄存器。
32位为64位寄存器的上半部分指定零的原因是它阻止了部分寄存器更新,这会导致指令流水线延迟。
在32或64位模式中使用16比特的码导致延迟在以下情形:
mov rax,-1 //1 cycle
mov ax,dx //1 cycle
//stall, the values of rax-upper and ax need to be combined
mov r8,rax //2 cycles
一个更好的选择是
mov rax,-1 //1 cycle
movzx eax,dx //runs concurrent with previous instruction, 0 cycles
mov r8,rax //1 cycle
//Total 2 cycles, twice as fast.
此代码是不等同于它上面的样品,但这就是整个观点。尽可能避免部分寄存器更新。 另请注意,由于上述原因,movzx eax,dx
相当于movzx rax,dx
。在x64上它缩短了一个字节,因此是首选的形式。
请注意,我没有使用ATT的语法,原则
+0
“更好的选择”的确速度更快,但不等同于原始的延迟代码。 'movzx'使初始的'mov'完全多余。另外,由于本答案前半部分给出的理由,可以更有效地将'movzx'编写为'movzx eax,dx'。 –
是的问题,但不是你想的原因。你也可以试试它。 – Jester
当然可以。无论您是使用8/16/32/64位模式寻址,它都是相同的寄存器。这是一个很好的图表:http://*.com/a/228367/14955 – Thilo
@Jester“不是你想的原因。”请详细说明。 – Thilo