4 ms·
Xor'ing registers isn't a compiler trick or arcane piece of lore, it's the canonical way to zero a register on most architectures. It's the only universally rec
by nickelpro 6y ago
Xor'ing registers isn't a compiler trick or arcane piece of lore, it's the canonical way to zero a register on most architectures. It's the only universally recommended way for both Intel and AMD x86 and x64 processors.
- FartyMcFarter 6y agoIn fact, modern x86 CPUs know that the result of "x XOR x" is independent of x, and use this fact to optimize operations that would otherwise have a dependency.
- tomtomtom777 6y agoYou are correct but using programmers terminology here is confusing. The opcodes 31 C0 mean "Set EAX register to zero" The opcodes 31 D8 mean "Set EAX to EAX xor EBX" The trick part is in the mnemonics used by assemblers and literature that transcribe the first as "XOR EAX, EAX". It isn't actually implemented as such, so it isn't really an "optimization"
- FartyMcFarter 6y agoI'm not sure what you mean by "programmers terminology". 0x31 0xC0 is disassembled to "xor eax, eax". This is not nitpicking, as there's an important difference. The "xor eax, eax" instruction affects CPU flags [1], while "mov eax, 0" doesn't [2]. > It isn't actually implemented as such The implementation is independent of the meaning of the instruction set. There are many implementations of x86 instructions with differing levels and kinds of optimization, so we can't make general statements about that. [1] https://c9x.me/x86/html/file_module_x86_id_330.html https://c9x.me/x86/html/file_module_x86_id_330.html [2] https://c9x.me/x86/html/file_module_x86_id_176.html https://c9x.me/x86/html/file_module_x86_id_176.html
- z3rgl1ng 6y agoHey, I didn't know this. I'm glad they shared it. Maybe instead of being a jerk, you could say: "Yes, as a matter of fact it's the canonical way..."
- bonzini 6y agoNot necessarily true for most architectures. Many RISC architectures have a "zero" register, so a canonical "move short immediate" instruction could be "OR Rn, R0, #n" ("OR R0 which is always zero with n and store into Rn") or the same with ADD. Then clearing Rn will usually be "OR Rn, R0, R0", "ADD Rn, R0, #0" or something like that.
- nickelpro 6y agoI should have been clearer, when I say most architectures I mean most x86/x64 architectures not most ISAs. Obviously ISAs with a dedicated zero register don't need the zeroing idioms of x86.
- bonzini 6y agoIn that case it's all of them. Some might like having both a MOV and a XOR in some special cases (one to avoid partial register stalls and one to avoid partial flags stalls, if I remember correctly) but even in those cases it's usually easy enough to avoid partial register stalls in some other way and just use XOR.
- danpalmer 6y agoThanks! Learning even more!
- Kwpolska 6y agoYou make it sound as if there were four Intel/AMD x86/x64 architectures. And well, there aren’t. The vendor split is not a thing, we’re all running the same software on Intel and AMD x86/x64 processors. And you could argue that the x86/x64 split doesn’t really matter for this, since x64 is a superset of x86 and inherits this tradition from the 16-bit and 32-bit eras.
- nickelpro 6y agoThere are dozens of x86/x64 uarchs, x86 is just an ISA, doesn't say anything about how the chip is built.