Live data from Hacker News

XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

devblogs.microsoft.com

81–90 of 231 posts

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#81

It should be noted that XOR is just (bitwise) subtraction modulo 2. There are many kinds of SUB instructions in the x86-64 ISA, which do subtraction modulo 2^64, modulo 2^32, modulo 2^16 or modulo 2^8. To produce a null result, any kind of subtraction can be used, and XOR is just a particular case of subtraction, it is not a different kind of operation. Unlike for bigger moduli, when operations are done modulo 2 addi…

> XOR is just a particular case of subtraction, it is not a different kind of operation.

It's different in that there's no carry propagation.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#82
post #34
post #10

Once an instruction has an edge, even if only extremely slight, that’s enough to tip the scales and rally everyone to that side. And this, interestingly, is why life on earth uses left-handed amino acids and right-handed sugars .. and why left handed sugar is perfect for diet sodas.

You still need to explain why this case creates a positive feedback loop rather than a negative one. I mean left/right fuel intakes in cars and male/female ratios somehow tend to balance at 50/50.

> left/right fuel intakes in cars

Are I believe chosen by intelligent humans who are deliberately trying to keep the lines at gas stations balanced.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#83
post #9
post #4

The obvious answer is that XOR is faster. To do a subtract, you have to propagate the carry bit from the least-significant bit to the most-significant bit. In XOR you don't have to do that because the output of every bit is independent of the other adjacent bits. Probably, there are ALU pipeline designs where you don't pay an explicit penalty. But not all, and so XOR is faster. Surely, someone as awesome as Raymond C…

His point is that in x86 there is no performance difference but everyone except his colleague/friend uses xor, while sub actually leaves cleaner flags behind. So he suspects its some kind of social convention selected at random and then propagated via spurious arguments in support (or that it “looks cooler” as a bit of a term of art). It could also be as a result of most people working in assembly being aware of the…

GP seems to think it strange that "x86" would actually not have a performance difference here.

I think this might just be due to not realizing just how far back in CPU history this goes.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#84
post #13

Earlier quoted context omitted.

From TFA: > It encodes to the same number of bytes, executes in the same number of cycles.

Those aren't the only resources. I could imagine XOR takes less energy because using it might activate less circuitry than SUB.

I'm not aware of any stories in the historical record of "real programmers" optimizing for power use, only for speed or code size.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#85
post #4

The obvious answer is that XOR is faster. To do a subtract, you have to propagate the carry bit from the least-significant bit to the most-significant bit. In XOR you don't have to do that because the output of every bit is independent of the other adjacent bits. Probably, there are ALU pipeline designs where you don't pay an explicit penalty. But not all, and so XOR is faster. Surely, someone as awesome as Raymond C…

Yea, that’s what immediately went through my head, too. XOR is ALWAYS going to be single cycle because it’s bit-parallel.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#86

Earlier quoted context omitted.

That comment is not very useful without pointing to realworld CPUs where SUB is more expensive than XOR ;) E.g. on Z80 and 6502 both have the same cycle count.

Harvard Mark I? Not sure why people think programming started with Z80.

My WW2-era assembly is a bit rusty, but I don't think the Harvard Mark 1 had bitwise logical operations?

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#87
post #4

The obvious answer is that XOR is faster. To do a subtract, you have to propagate the carry bit from the least-significant bit to the most-significant bit. In XOR you don't have to do that because the output of every bit is independent of the other adjacent bits. Probably, there are ALU pipeline designs where you don't pay an explicit penalty. But not all, and so XOR is faster. Surely, someone as awesome as Raymond C…

> The obvious answer is that XOR is faster. It used to be not only faster but also smaller . And back then this mattered. Say you had a computer running at 33 Mhz, you had 33 million cycles per second to do your stuff. A 60 Hz game? 33 million / 60 and suddenly you only have about 500 000 cycles per frame. 200 scanlines? Suddenly you're left with only 2500 cycles per scanline to do your stuff. And 2500 cycles really…

The context was comparison to SUB EAX,EAX, not to a MOV.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#88

Earlier quoted context omitted.

But energy consumption could be different for this hypothetical 0.5 and 0.9.

Energy consumption wasn't really a concern when the idiom developed. I don't think people really cared about the energy consumption of instructions until well into the x86-64 era.

Not sure why this is being downvoted, but it’s absolutely correct. For most of the history of computing, people were happy that it worked at all. Being concerned about energy efficiency is a recent byproduct of mobile devices and, even more recently, giant amounts of compute adding up to gigawatts.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#89
post #27

Earlier quoted context omitted.

Quite a few architectures have a dedicated 0 register.

Indeed!! MIPS - $zero RISC-V - x0 SPARC - %g0 ARM64 - XZR

PowerPC: "r0 occasionally" (with certain instructions like addi, though this might be better considered an edge case of encoding)

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#90
post #27

Earlier quoted context omitted.

Quite a few architectures have a dedicated 0 register.

Yep. The XOR trick - relying on special use of opcode rather than special register - is probably related to limited number of (general purpose) registers in typical '70 era CPU design (8080, 6502, Z80, 8086).

A move on SPARC is technically an OR of the source with the zero register. "move %l0, %l1" is assembled as "or %g0, %l0, %l1". So if you want to zero a register you OR %g0 with itself.
Post reply on HN