32 位和 64 位值是否共享同一个寄存器 space?

Do 32 and 64 bit values share the same register space?

如果我从 32 位寄存器中移动一个值,请说:

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

存储在 %rax 中的值会被破坏吗?

是的,

您的代码:

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 语法