Jump to content

The Magic of EOR

Posted by Omegamatrix, in Assembly Tricks 21 June 2014 · 1,236 views

EOR is a useful function. I often use it in a situation where I already have "myNumber" in the accumulator, and I want to do a subtraction. Instead of doing this:
    sta    temp       ; myNumber (0 to 255)
    lda    #$FF       ; 255
    sbc    temp       ; 255 - myNumber
You can just do this:
    eor    #$FF       ; 255 - myNumber
You save a lot of cycles and bytes. You can apply the same idea in other situations. Another common one is EOR $0F with a value of 0-15 to get the result of 15 - myNumber. You can also preserve signed bits while flipping the other used bits... although I've never really played around with that as I only ever seem to use positive values.
EOR is also useful to help optimize a look up table. Here is a routine I once wrote to dynamically convert a color from NTSC to PAL. EOR saves me several cycles here, because I can predetermine what bits I need to flip. It's a lot easier then storing a nibble to a temp register, OR'ing it later, etc...
    tax ; save current NTSC color
    eor    ConvertColTab,Y ; color is now PAL


    .byte $00 ; $0x ---> $0x
    .byte $30 ; $1x ---> $2x  could also use ".byte $20", $1x ---> $3x
    .byte $00 ; $2x ---> $2x
    .byte $70 ; $3x ---> $4x
    .byte $20 ; $4x ---> $6x
    .byte $D0 ; $5x ---> $8x
    .byte $C0 ; $6x ---> $Ax
    .byte $B0 ; $7x ---> $Cx
    .byte $50 ; $8x ---> $Dx
    .byte $20 ; $9x ---> $Bx
    .byte $30 ; $Ax ---> $9x
    .byte $C0 ; $Bx ---> $7x
    .byte $90 ; $Cx ---> $5x
    .byte $E0 ; $Dx ---> $3x
    .byte $D0 ; $Ex ---> $3x
    .byte $D0 ; $Fx ---> $2x
Then there is also a famous EOR trick to swap two values without using a temp register (or X and Y):
    lda    ValueOne
    eor    ValueTwo
    sta    ValueTwo
    eor    ValueOne
    sta    ValueOne
    eor    ValueTwo
    sta    ValueTwo
I find this mostly academic though. It wastes a lot of cycles, and bytes. If you really don't have a temp register left then your code has other problems. Still a neat trick though. :)
Here is something useful that a user on NesDev named tepples showed me. Without delving into the code, I'm basically in a situation where I'm splitting the nibbles apart (although the top nibble is also times by 4). My code:
    lda    hexHigh               ;3  @3
    and    #$F0                  ;2  @5
    lsr                          ;2  @7
    lsr                          ;2  @9
    tay                          ;2  @11
    lda    hexHigh               ;3  @14
    and    #$0F                  ;2  @16
    tax                          ;2  @18
And his code with EOR:
    lda    hexHigh               ;3  @3
    and    #$0F                  ;2  @5
    tax                          ;2  @7 
    eor    hexHigh               ;3  @10
    lsr                          ;2  @12
    lsr                          ;2  @14
    tay                          ;2  @16
That saves 2 bytes and 2 cycles. I was so impressed with that bit of code. I can't begin to tell you how many times I've come across this and similar situations. I've never thought about blowing the other nibble away like that (maybe you guys have). I've always known that if you EOR something with the same value then you get 0, but it just never occurred to me to use it in this situation. I was so happy with this solution. I've been thinking about that simple trick for days. :D

just came across your text. Thanks for sharing your adventures with EOR :)

  • Report

Interesting: I will keep in mind!

  • Report
That color conversion trick is slick!
  • Report

March 2019

24 25 2627282930

Recent Comments

Latest Visitors

0 user(s) viewing

0 members, 0 guests, 0 anonymous users