32位和64位值共享相同的寄存器空间吗?

问题描述:

如果我提出从32位寄存器中的值说:32位和64位值共享相同的寄存器空间吗?

movq %rdx,%rax 
    movl %edx,%eax 

将存储在%rax中的价值得到打一顿?

+0

是的问题,但不是你想的原因。你也可以试试它。 – Jester

+0

当然可以。无论您是使用8/16/32/64位模式寻址,它都是相同的寄存器。这是一个很好的图表:http://*.com/a/228367/14955 – Thilo

+0

@Jester“不是你想的原因。”请详细说明。 – Thilo

是,

您的代码:

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'。 –