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!
|