5 ms·
Can you explain the example? // test.asm main: movb $1, 53280 xorl %eax, %eax ret And get this output: main: ldy #$1 sty 53280
by KSS42 10y ago
Can you explain the example?
// test.asm
main:
movb $1, 53280
xorl %eax, %eax
ret
And get this output:
main:
ldy #$1
sty 53280
lda $00
rts
I can see "movb $1, 53280" getting mapped to:
ldy #$1
sty 53280
but what is going on with the xorl and lda?
- tux1968 10y agoxor'ing a register against itself is an idiomatic way to clear the register to 0. Could do the same thing in 6502, but loading with zero directly is functionally equivalent.
- KSS42 10y agoThanks for the explanation. In the x86 code, is there an advantage of using the xor instead of a load/mov? Is it to avoid a fetch? (I programmed 6502/6510 assembly as a kid, but have no experience with x86 assembly)
- CJefferson 10y agoThe xor is shorter.
- strangecasts 10y agoYeah, it's shorter and it doesn't touch any other registers.
- alblue 10y agoThe encoding of the machine instruction is 2 bytes for xor eax,eax - if you were doing a load/mov then you'd have to use a numeric cknstant which would be 4 bytes to represent zero and then more for the mov itself. In addition when you have dependent loads of registers between instructions you can end up with pipeline stalls that delay the instruction (even if it shouldn't have any logical effect). The xor pattern is so common that inside the processor (which translates isa instructions to microcode) recognise it explicitly and so it's treated as a special case. In fact no xor happens and the register is simply reprinted to a fresh value containing zero.
- 13of40 10y agoI've always wondered why a CISC architecture like x86 didn't include a CLR instruction...
- Annatar 10y agoOn some processor families, like for instance the MC68000 family of processors, the clr instruction always wastes at least one clock cycle reading the register being cleared before actually clearing it, which is why when you look at the assembler code for that processor family, you will rarely see the clr instruction being used: http://www.easy68k.com/paulrsm/doc/trick68k.htm http://www.easy68k.com/paulrsm/doc/trick68k.htm common tricks to clear out a data register on the 68000 family in a performant way include: moveq #0, d0 ; this works because zero can be expressed with only seven bits eor.l d0, d0 sub.l d0, d0 and for the address register sub.l a0, a0 eor.l a0, a0
- Someone 10y agoFor those that want more details, there's https://randomascii.wordpress.com/2012/12/29/the-surprising-subtleties-of-zeroing-a-register/ https://randomascii.wordpress.com/2012/12/29/the-surprising-...
- to3m 10y agoBut part of the bizarre genius of the 6502 is that you can't do the same thing. OK, sure, so you could do this, and it does indeed EOR the accumulator with itself. STA $70 ; 2 3 EOR $70 ; 4 6 But that's stupid, because nobody would waste a zero page byte like that. Perhaps you have heard of this thing called "best practice"? With that in mind, here is some self-modifying code. STA L+1 ; 3 4 L: EOR #$FF ; 5 6 Much better. The accumulator is EORed with itself just the same, and this time nobody can accuse you of being unprofessional. Of course, if the latter approach is less stupid, that's only in relative terms. Because you could also do this. LDA #0 ; 2 2
- SixSigma 10y agoThe bizarre "genius" of x86 is that exactly that thing gets done in microcode as a special case.
- Annatar 10y agoExcept that lda $00 loads the accumulator with the value of the zero page address $0, instead of clearing the accumulator. To clear it, the code should have been: lda #$00
- KSS42 10y agoGood catch.