# Single bit XOR in 8051

#### cmartinez

Joined Jan 17, 2007
7,063
This is embarrassing... I consider myself an expert in the 8051 architecture, but I've never had to perform a single bit xor operation before.

What I want to do is fairly simple, I want C = XOR(DOWN_FLAG, UP_FLAG). I've performed plenty of byte-to-byte XRL operations before, but I've never had the need to perform a bit-to-bit xor, until now.

This is how the code would look like if the XRL C, bit instruction existed (which it doesn't ... numbers in parenthesis are the clock cycles performed by each instruction in an AT89LP4052):

Code:
   MOV DOWN_FLAG, C   ;(2)
XRL C, UP_FLAG     ;(?)
JC CHECK_UP_DOWN_INPUTS_EXIT ;(3)
But since the stupid bit-to-bit XRL instruction doesn't exist, I've been forced to translate them into bytes and performing XRL there.

Code:
   MOV DOWN_FLAG, C   ;(2)
CLR A              ;(1)
MOV A.0, C         ;(2)
MOV C, UP_FLAG     ;(2)
MOV B, #00H        ;(3)
MOV B.0, C         ;(2)
XRL A, B           ;(2)
JNZ CHECK_UP_DOWN_INPUTS_EXIT ;(3)
This bothers me because it seems like an awful waste of cycles and instructions for such a simple task. And I know that a standard gate XOR instruction (which can easily be translated to code) looks like this.

But it still looks like an awful number of steps. Is there an easier way?

#### JohnInTX

Joined Jun 26, 2012
4,239
My 8051 is rusty so I might not be getting how you are storing UP_FLAG and DOWN_FLAG but the trick is to perform normal byte operations on the whole register-even the bit addressable ones- then just strip off the other bits in the result by ANDing.
If the flags are corresponding bits in two registers, just XRL the two registers to A, and ANL A, #mask to strip off the unused bits then check for Z.

If the flags are not aligned (2 bits in the same register or random different bit locations in different registers) load one register to A, rotate A to align the first flag under the other flag in its register then XRL A with the register, ANL with the mask and check for Z.

The ANL mask is constructed to have a '1' where the flags are and zeros in the other 7 bits i.e.
ANL A,#80h would expect both flags to have been stored or rotated to the MSbit for the byte-wide XRL operation.

Apologies if I'm misunderstanding the problem and for sketchy 8051 code...
Code:
; Don't remember how to specify the bits but you get the idea
UP_FLAG equ 20h.0   ; addressable bit 0 (MSbit of addressible segment register at 20h)
DOWN_FLAG equ 20h.1   ; addressable bit 1 (next bit of same register)

mov A,20h     ; get the register with the flags to A
RL  A       ; rotate one bit left, DOWN_FLAG is now MSbit of A and aligned with UP_FLAG in the register
XRL A,20h     ; XOR, the two MSbits are valid. Ignore the others
ANL A,#80h     ; strip off unused bits. Z/NZ indicates XOR result on the 2 flags
JZ FlagsWereTheSame

Last edited:

#### cmartinez

Joined Jan 17, 2007
7,063
Thanks, John. But I think I already solved it:

Code:
   CHECK_DOWN_FLAG:
JNB, DOWN_FLAG, CHECK_UP_FLAG ;(3) if down_flag was cleared, then compare with up_flag
JB UP_FLAG, CLEAR_ALL_FLAGS   ;(4) if up_flag was also set, clear both flags
JMP CHECK_UP_DOWN_INPUTS_EXIT  ;(3) otherwise, exit directly

CHECK_UP_FLAG:                  ;DOWN_FLAG was cleared
JB UP_FLAG, CHECK_UP_DOWN_INPUTS_EXIT ;(4) if up_flag is set, exit directly, clear both flags if not

CLEAR_ALL_FLAGS:
CLR UP_FLAG                    ;(2)
CLR DOWN_FLAG                  ;(2)

CHECK_UP_DOWN_INPUTS_EXIT:
What an annoying pain in the (_*_) ... really ...

#### cmartinez

Joined Jan 17, 2007
7,063
I like your routine, though. I'm going to evaluate it against mine... see which one is the most efficient ... the loser pays the next round of beers!

#### JohnInTX

Joined Jun 26, 2012
4,239
I like your routine, though. I'm going to evaluate it against mine... see which one is the most efficient ... the loser pays the next round of beers!
Deal!
And to increase my odds, keep in mind that you can eliminate the rotation(s) by judicious selection of where the flags are located i.e. bits 0 and 8 are MSbits in different bit-mapped registers.
mmmm.. beer

Last edited:

#### BobaMosfet

Joined Jul 1, 2009
1,185
This is embarrassing... I consider myself an expert in the 8051 architecture, but I've never had to perform a single bit xor operation before.

What I want to do is fairly simple, I want C = XOR(DOWN_FLAG, UP_FLAG). I've performed plenty of byte-to-byte XRL operations before, but I've never had the need to perform a bit-to-bit xor, until now.

This is how the code would look like if the XRL C, bit instruction existed (which it doesn't ... numbers in parenthesis are the clock cycles performed by each instruction in an AT89LP4052):

Code:
   MOV DOWN_FLAG, C   ;(2)
XRL C, UP_FLAG     ;(?)
JC CHECK_UP_DOWN_INPUTS_EXIT ;(3)
But since the stupid bit-to-bit XRL instruction doesn't exist, I've been forced to translate them into bytes and performing XRL there.

Code:
   MOV DOWN_FLAG, C   ;(2)
CLR A              ;(1)
MOV A.0, C         ;(2)
MOV C, UP_FLAG     ;(2)
MOV B, #00H        ;(3)
MOV B.0, C         ;(2)
XRL A, B           ;(2)
JNZ CHECK_UP_DOWN_INPUTS_EXIT ;(3)
This bothers me because it seems like an awful waste of cycles and instructions for such a simple task. And I know that a standard gate XOR instruction (which can easily be translated to code) looks like this.

But it still looks like an awful number of steps. Is there an easier way?
But you do know what a mask is, right? You access individual bits using masks.