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

时间:2017-04-26 00:25:12

标签: assembly x86-64 att

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

for _ in 0..<1000 {
   value -= 1
}

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

1 个答案:

答案 0 :(得分:2)

是,

您的代码:

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语法,原则上