Why xor eax, eax?

https://news.ycombinator.com/rss Hits: 15
Summary

Why xor eax, eax? Written by me, proof-read by an LLM. Details at end. In one of my talks on assembly, I show a list of the 20 most executed instructions on an average x86 Linux desktop. All the usual culprits are there, mov, add, lea, sub, jmp, call and so on, but the surprise interloper is xor - “eXclusive OR”. In my 6502 hacking days, the presence of an exclusive OR was a sure-fire indicator you’d either found the encryption part of the code, or some kind of sprite routine. It’s surprising then, that a Linux machine just minding its own business, would be executing so many. That is, until you remember that compilers love to emit a xor when setting a register to zero: We know that exclusive-OR-ing anything with itself generates zero, but why does the compiler emit this sequence? Is it just showing off? In the example above, I’ve compiled with -O2 and enabled Compiler Explorer’s “Compile to binary object” so you can view the machine code that the CPU sees, specifically: 31 c0 xor eax, eax c3 ret If you change GCC’s optimisation level down to -O1 you’ll see: b8 00 00 00 00 mov eax, 0x0 c3 ret The much clearer, more intention-revealing mov eax, 0 to set the EAX register to zero takes up five bytes, compared to the two of the exclusive OR. By using a slightly more obscure instruction, we save three bytes every time we need to set a register to zero, which is a pretty common operation. Saving bytes makes the program smaller, and makes more efficient use of the instruction cache. It gets better though! Since this is a very common operation, x86 CPUs spot this “zeroing idiom” early in the pipeline and can specifically optimise around it: the out-of-order tracking systems knows that the value of “eax” (or whichever register is being zeroed) does not depend on the previous value of eax, so it can allocate a fresh, dependency-free zero register renamer slot. And, having done that it removes the operation from the execution queue - that is the xor takes zero execution cycles...

First seen: 2025-12-01 13:50

Last seen: 2025-12-02 03:52