THE
XOR TRICK


 P1  Pick A PIC Project

 

 

 
Here is a list of the capabilities of the XOR function: 

xorlw     0fh    ;EXclusively OR a value with w 
xorfw     test   ;EXclusively OR a file with w

To toggle a bit or bits:
toggle movlw  10h      ;Put 0001 0000 into w to toggle GP4  
          xorwf  gpio,f    ;the only bit that will change is bit4

Match two files   (see below)
Exchange two files  (see below)
Copy bits from one file to another (see below)
Complement bits in a file (see below)
Create an "In-Line" table  (see below)


We have called this article "The XOR Trick" to capture your attention.
The XOR instruction can perform amazing results in a single instruction but it must be fully understood BEFORE using it.
Most of the 35 instructions for the micros we are studying are easy to understand and it's easy to see a result, but the XOR function must be checked by "by-hand" to prove what is happening. If you don't do this, it will be impossible to find a problem, if a problem arises in your program. 
I am not saying a problem will always result from using XOR, but you must check the result "by-hand" to confirm the result is what you expect. Many of the following examples come from highly qualified programmers, who like to save a few bytes, but produce extremely "clever" and "complex" instructions, in the process.
They complain I am "over-stressing" the situation and cannot see the complex nature of this type of programming, but there has always been the situation of "professors not being able to communicate with their students."
That's why these highly intellectual individuals are hopeless at teaching. They can't see why you don't understand advanced programming. And any time the XOR instruction is used, it takes "concentrated thinking" to see what is occurring.
So, let's look at the capability of the XOR instruction.  It's one of a number of Boolean commands in the list of instructions and can create a single line of code that can take 10 lines to explain.
The XOR command is spoken as: "Exclusive OR" and is sometimes written EOR or E-OR.
It has the caret symbol "^" when writing assembly code and you will also find some very unusual symbols for XOR, that cannot be reproduced on the conventional keyboard.
It is exclusively an OR situation, whereas the standard OR function includes the possibility of both inputs being HIGH for a HIGH output and this is the difference - as you will see below.
The simplest TRUTH TABLE for the XOR function involves two inputs - sometimes called A and B. These inputs can also be called "arguments."  An input is "true" when it is HIGH and "false" when it is LOW.
XOR can be described verbally as, "Either A or B, but not both."
The output or RESULT of each possibility is shown in the truth table below. The symbol "^" is the common symbol (used in C++ programming, etc) for bit-level XOR. In other words, it is used for manipulation bits in a file and the result is shown in the "output" column: 
 

XOR Truth Table

Input A

Input B

A^B

LOW

LOW

LOW

LOW

HIGH

HIGH

HIGH

LOW

HIGH

HIGH

HIGH

LOW

When you look at any truth table, the "item" or "word" or "condition " or "state" you are looking for in the INPUTS column is: HIGH or T or TRUE. Then look at the state of the OUTPUT. It is only the HIGHs that concern us. The only two HIGH results are for a single HIGH as an input.

What's the difference between the OR function and the XOR function?
The OR gate produces a result according to: "If A is 1 OR B is 1 (or both are 1), then the output is 1."  Note that this function produces an output when both inputs are HIGH.  - the XOR removes this result. The OR function is also called the Inclusive OR as it includes the result when both inputs are HIGH. This corresponds to the AND function for 2-inputs. Because of the ambiguity of the inputs (we don't know exactly the state of the inputs), we use the exclusive-OR function for determining the outcome of the INPUTS we are testing.  The symbol (|) indicates OR.

OR Truth Table  or =(|)

Input A

Input B

A or B

LOW

LOW

LOW

LOW

HIGH

HIGH

HIGH

LOW

HIGH

HIGH

HIGH

HIGH

The XOR function also works with multiple inputs and the output is defined to be TRUE if an odd number of its arguments (inputs) are true, and false otherwise.
In this discussion we will only cover the case of 2 inputs as this corresponds to the capabilities of assembly programming for the microcontrollers we are covering.

The XOR function is very powerful and will create a result that may take a minute or more for you to work out "by hand." But you can confirm exactly what is happening, by performing the XOR calculations yourself.

WHAT DOES THE XOR INSTRUCTION DO?
The XOR instruction can be found in the list of instructions as:   xorlw   and xorwf 
These instructions mean:
Example 1:   xorlw     0fh      ;Exclusively OR the number (literal - 0f hex) with w
Example 2:   xorfw     test      ;Exclusively OR the value in file: "test" with w

You can see how complex each of the above instructions can be. For Example1:
Firstly you need to know the value in w. Suppose it is
b'0001 0011' 
and the literal is: b'0000 1111.'
Perform a XOR addition:
    0001 0011
    0000 1111
    0001 1100    the result is: b'0001 1100' 

For Example2:  You need to know the value in w and the value in "test" file.

MORE THINGS CAN BE DONE WITH THE XOR FUNCTION
One of the simplest things that can be done with the XOR instruction is to change one, two, three . . .  or all of the outputs (bits) of a port (or any file) from LOW to HIGH or HIGH to LOW or a mixture. 
The instruction changes the sign of each bit and all 8 bits (output lines) of a port will be changed from the original state to the opposite stage. This means any LEDs (up to 8) on an output, that were illuminated, will be turned off and any non-illuminated LEDs will be illuminated. The same applies to the bits in a file. Any number of bits can be changed from "0" to "1" or "1" to "0." We do not have to know the original state of any of the bits. By creating a "toggling number" any bits with "1" will create a toggle.

TOGGLING
We can write an instruction that selects a particular output bit (LED) and changes the state of only this bit. This will turn a LED on or turn it off.
If the bit is ON, it will be turned OFF. And if the instruction is processed again, the bit will be turned ON. This is called TOGGLING. With this instruction we do not have to know the state of the bit. It can be "1" or "0." The instruction will simply change the state.

Here are the instructions for toggling a bit:  (see more on TOGGLING: Library of terms  P-Z)

toggle movlw  10h      ;Put 0001 0000 into w to toggle GP4         
       xorwf  gpio,f   ;the only bit that will change is bit4

MATCHING TWO FILES = COMPARISON = COMPARE
We can also use the XOR function to detect a MATCH between two files.
To find out if two numbers are the same, they are XOR-ed together. Since each binary digit (bit) will be the same, the result will be (0000 0000). For example, if we have two files:
b'0001 0011'    and   b'0001 0011'  bit0 in each file is '1'   bit1 in each file is "1"  bit2 in each file is "0"  etc etc etc. In fact all bits are the same. When all bits are the same, this will SET the zero flag in the Status (03) file and by testing bit 2 (the z flag) you can include an instruction in your program to skip the next instruction when the z bit is set.

Here are the instructions for matching two files:

match  movlw   0Ch        ; load 0Chex into w      
       xorwf   motor      ; see if "motor" file holds 0Chex          
       btfss   status,2   ; test the z flag to see if it is SET      
       goto    notsame    ;z flag is not set
       goto    same	  ;z flag set = files are both 0Chex

EXCHANGE THE CONTENTS OF A FILE WITH W

This code exchanges the contents of a file with the w register.  It doesn't require the use of another file to store an intermediate value. file holds: b'0001 1100'   w holds:b'0000 1111'
f_x_w xorwf  file,f   ;before: file=b'0001 1100' w=b'0000 1111'
                      ;after: file=b'0001 0011'  w=b'0000 1111'   
      xorwf  file,w   ;after: file=b'0001 0011' w=b'0001 1100'     
      xorwf  file,f   ;after: file=b'0000 1111' w=b'0001 1100'     

EXCHANGE THE CONTENTS OF TWO FILES
This code exchanges the contents of two files using the w register.  It doesn't require the use of another file to store an intermediate value.
exch  movf   file2,w   ;file1=b'0001 0011' file2=b'0000 1111'  
                       ;w=b'0000 1111' (after execution) 
      xorwf  file1,f   ;file1=b'0001 1100' w=b'0000 1111'        
      xorwf  file1,w   ;file1=b'0001 1100' w=b'0001 0011'     
      xorwf  file1,f   ;file1=b'0000 1111' w=b'0001 0011'
      movwf  file2     ;file2=b'0001 0011'

RANDOM NUMBER GENERATOR

rand     movlw    01Dh         ;any value can be used
           clrc                        ;clear carry
           rlf          random,f    ; rotate random file left
           btfsc     status,c     ;test the carry bit (bit0) in Status file
           xorwf    random,w   ;xor w with random and put result in w
           retlw     00


COPY BITS FROM ONE FILE TO ANOTHER

copy   movf    from_file,w
          xorwf   to_file,w
          andlw  b'xxxxxxxx'  ;replace "x" with "1" to copy the bit or "0" to leave bit as is.
          xorwf   to_file,f

BITWISE OPERATIONS
Operating on the bits of a file (or two files) is called a BITWISE OPERATION. 


COMPLEMENTING BITS
An "XOR mask" complements (reverses) selected bits of a file. This is called a BITWISE ARITHMETIC OPERATION. 
 The MASK is loaded into w and XOR'ed with fileA.

reverse 
movlw    b'00000011'    ;this is the MASK to reverse the two lowest bits
                                              ;fileA contains
b'11111101'  (before)
            xorwf      fileA,f            ; fileA contains 
b'11111110'  (after)


HOW THE XOR OPERATOR WORKS:
Here is a summary of how the XOR operator works:
^ is the XOR operator (0^0 = 0, 0^1 = 1, 1^0 = 1, 1^1=0).
Any value XOR'd with itself results in 0 (X^X=0)
XORing with zero has no effect (0^X=X)



INLINE TABLE

An "Inline Table" is a table that does not use a "call and return" feature.
Here is a 5 element table:

   addwf   pcl,f    
   xorlw   3^00^(2^01)     ;the table-value is 3
   xorlw   2^01^(7^02)     ;the table-value is 2
   xorlw   7^02^(5^03)     ;the table-value is 7 
   xorlw   5^03^(1^04)     ;the table-value is 5 
   xorlw   1^04            ;the table-value is 1 
   movwf   tempA
   (the program will use the value in tempA to display a value on 
      a 7-segement display or something similar then go to an 
      address above addwf pcl,f to change the value for w to jump to another table-value)
Before entering the above instructions, the program will need to load w with a value from 0 to 4 so that when the instruction addwf  pcl,f is executed, the micro will jump down the appropriate number of table-values and enter at the correct location. 
If the value for the table is "0," the first table-value will be executed 3^00^(2^01) and then the next line: 2^01^(7^02) and the following three lines will also be executed to produce a value of 3 to be placed in tempA.
This is a very complex way of achieving a table-value but it shows how the XOR operator works. And it is the only way to produce an "in-line" table.
Each table-value consists of three items. The first item is the actual table-value. The second item is the value that w will contain when it enters the table and third item is a copy of the  first and second values in the next table-row.
To work out what is happening, you must remember the two rules for XOR'ing:
Any value XOR'd with itself results in 0 (X^X=0)
XORing with zero has no effect (0^X=X)

If we take the fourth table-value, w will enter with the value 03 and perform an XOR on 5^03^(1^04) then advance to the next line and perform an XOR on 1^04. W will contain 5.
If we place all the values in a single line they become: 03^5^03^(1^04)^1^04.
The 03^03=0 and
(1^04)^1^04=0 leaving 5^0^0=5.
If the micro enters the first line, the five lines of XOR'ing would be: 0^3^00^(2^01)^2^01^(7^02)^7^02^(5^03)^5^03^(1^04)^1^04=3.

Now you can see why it might take a few minutes to work out what is happening in a 10 line "in-line" table!

 

 5/7/2010