4 ms·
> In this case, even though rax is needed to hold the full 64-bit long result, by writing to eax, we get a nice effect: Unlike other partial register writes, wh
by ethin 11mo ago
> In this case, even though rax is needed to hold the full 64-bit long result, by writing to eax, we get a nice effect: Unlike other partial register writes, when writing to an e register like eax, the architecture zeros the top 32 bits for free. So xor eax, eax sets all 64 bits to zero.
I had no idea this happened. Talk about a fascinating bit of X86 trivia! Do other architectures do this too? I'd imagine so, but you never know.
- 201984 11mo agoAArch64 also zeroes the upper 32 bits of the destination register when you use a 32 bit instruction.
- flykespice 11mo agoI'm curious, why is that? I know x86-64 zeroes the upper part of the register for backwards compability and improve instruction cache (no need for REX prefix), but AArch64 is unclear for me.
- School-Cotton 11mo agoI don't know either, but why wouldn't backwards compatibility apply to aarch64? It too is based on a pre-existing 32-bit architecture.
- Narishma 11mo agoI don't think it's backwards compatible the same way x86-64 is.
- 201984 11mo agoIt's to break dependencies for register renaming. If you have an instruction like mov w5, w6 // move low 32 bits of register 6 into low 32 bits of register 5 This instruction only depends on the value of register 6. If instead it of zeroing the upper half it left it unchanged, then it would depend on w6 and also the previous value of register 5. That would constrain the renamer and consequently out-of-order execution.
- zeuxcg 11mo agoYou really want to avoid a dependency on prior content of the destination register, to allow renaming and maximize out of order scheduling.
- monocasa 11mo agoA lot of the RISC architectures do something similar (sign extend rather than zero extend) when using 32 ops on a 64 bit processor. MIPS and PowerPC come to mind off of the top of my head. Being careful about that in the spec basically lets them treat 32-bit mode on a 64-bit processor as just 'mask off the top bits on any memory access'. Some of these processors will even let you use 64bit ops in 32bit mode, and really only just truncate memory addresses. So the real question is why does x86 zero extend rather than sign extend in these cases, and the answer is probably that by zero extending, with an implementation that treats a 64bit architectural register as a pair 32bit renamed physical registers, you can statically set the architectural upper register back on the free pool by marking it as zero rather than the sign extended result of an op.