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 语法
如果我从 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 语法