Live data from Hacker News

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

devblogs.microsoft.com

221–230 of 231 posts

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

#221
post #88

Earlier quoted context omitted.

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.

This take is anachronistic. Thermal issues were evident by the late 1990's. Of course by that time not many were working in x86 assembly but embedded systems sure cared about power. People forget embedded predated mobile by a good 20 years.

Nintendo's original Game Boy lasted 40 hours on two AA batteries in 1989. You can't reach those numbers without engineering for energy efficiency.

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

#222

XOR is a simple logic-gate operation. SUB would have to be an ALU operation. A one-bit adder (which is subtraction in reverse) makes signals pass through two gates. See https://en.wikipedia.org/wiki/Adder_(electronics) You need the 2 gates for adding/subtracting because you care about carry. So if you're adding/subtracting 8 bits, 16 bits, or more, you're connecting multiples of these together, and that carry has to…

That's all true, but on any modern x86 processor both the single pair of gates for the xor and the 10 or so for a carry-bypass 64 bit wide subtraction both happen with a single clock cycle of latency so from a programmer's perspective they're the same in that sense. There's still an energy difference but its tiny compared to what even the register file and bypass network for the operation use, let along the OoO struc…

So then the question is: which pipeline is used less? Bit or add?

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

#223

Earlier quoted context omitted.

Could be used to express 1 bit of information in some non-obvious convention.

The x86-64 ISA provides a lot of alternative encodings for the same instruction or for instructions that are equivalent. It has already been suggested to use these for steganography, i.e. for embedding a hidden message in a binary executable file, by encoding 1 or more bits in the choice of the instruction encoding among alternatives, for every instruction for which alternatives exist.

The shareware assembler a86 used to use this to fingerprint its output so the author could check whether random programs to see if they were assembled using it without having paid the shareware fee.

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

#224
post #95

Earlier quoted context omitted.

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

The article is about x86, and x86 assembly is mostly a superset of 8080 (which is why machine language numbers registers as AX/CX/DX/BX, matching roughly the function of A/BC/DE/HL on the 8080—in particular with respect to BX and HL being last).

So you say x86 wasn't made ex nihilo, but evolved from previous designs? When this evolution began? 8080 followed 8008, code for which was written in macro-11 https://en.wikipedia.org/wiki/PDP-11_architecture#Example_co...

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

#225
post #217

Earlier quoted context omitted.

You're absolutely right, I stand corrected. The 6502 gets by doing immediate load: 2 clock cycles, 2 bytes (frequently followed by single byte register transfer instruction). Out of curiosity I did a quick scan of the MOS 1.20 rom of the BBC micro: LDY #0 (a0 00): 38 hits LDX #0 (a2 00): 28 hits LDA #0 (a9 00): 48 hits

Are you sure you're not an LLM? There is no way anybody writing 6502 would do anything else, because there's no other way to do it. (You can squeeze in a cheeky Txx instruction afterwards to get a 2-or-more-for-1, if that would be what you need - but this only saves bytes. Every instruction on the 6502 takes 2+ cycles! You could have done repeated immediate loads. The cycle count would be the same and the code would…

> Are you sure you're not an LLM?

Hard to tell, but I don't think so ;-)

I suppose using Txx instructions rather than LDx is more of an idiom than intended to conserve space. Also, could an LDx #0 potentially be 3 cycles in the edge case where the PC crosses a page boundary? (I'm probably confused? Red herring?)

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

#226
> I don’t know why xor won the battle, but I suspect it was just a case of swarming.

> In my hypothetical history, xor and sub started out with roughly similar popularity, but xor took a slightly lead due to some fluke, perhaps because it felt more “clever”.

SO MUCH ink and "odd" code has been spilled over these 2 sentences over the past few decades...

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

#227
post #216

Earlier quoted context omitted.

I'm studying 4-bit-slice processors from the 1970s. This is all tangent to the x86 discussion. Minicomputer processors! I have two bit-slice machines from TI based on the 74S481 (4-bit slice x 4). Just like with the 74181, all ALU operations go through the same path, there are just extra gates that make the difference between logical or arithmetic. For instance, for each bit in the slice, the carry path is masked out…

Thanks, I suspected there might be something from the minicomputer era. I've only really looked at a single AM2900 implementation (and it was far from optimal). Guess I need to dig deeper at some point. > The ONES operation forces all the carry chain to 1 (ignoring operand) (you can do a ONES+1 to get arithmetic 0, but why?) Forcing all carries to 1 inverts the output. If I'm understanding the ALU correctly, (the dat…

I'll have to rethink what goes on in the ONES operation. The gate level schematic for the 74181 I found in a databook.

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

#228

Earlier quoted context omitted.

That's just not true. You think subtracting/adding 64-bit numbers actually take 64 cycles? There is sequential implementation of ripple carry adder that uses clock and register, this will add 1-bit per cycle, but no body uses this for obvious reason, it's just a toy example for education. A normal ripple carry adder will have some delay in propagation time before the output is valid, but that is much less a clock cyc…

> but no body uses this for obvious reason, it's just a toy example for education. SERV has entered the chat! It has one upside besides education, and that is that it can be implemented with fewer gates. If you for some reason need parallelism on the core level rather than the bit level, you can cram in more cores with bit-serial ALUs in the same space.

SERV also implements xor bit serially too though.

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

#229
post #217

Earlier quoted context omitted.

Are you sure you're not an LLM? There is no way anybody writing 6502 would do anything else, because there's no other way to do it. (You can squeeze in a cheeky Txx instruction afterwards to get a 2-or-more-for-1, if that would be what you need - but this only saves bytes. Every instruction on the 6502 takes 2+ cycles! You could have done repeated immediate loads. The cycle count would be the same and the code would…

> Are you sure you're not an LLM? Hard to tell, but I don't think so ;-) I suppose using Txx instructions rather than LDx is more of an idiom than intended to conserve space. Also, could an LDx #0 potentially be 3 cycles in the edge case where the PC crosses a page boundary? (I'm probably confused? Red herring?)

I don't know how the 6502's PC increment actually worked, but it was an exception to the general rule of page crossings (or the possibility thereof) incurring a penalty, or, as was also sometimes the case, just ignored entirely. (One big advantage of the latter approach: doing nothing does take 0 cycles.)

The full 16 bits would be incremented after each instruction byte fetched, and it didn't cost any extra if there was a carry out of the MSB.

Post reply on HN