Tra gli operatori booleani a volte viene poco con siderato XOR.
Questo operatore, ben conosciuto da chi si occupa di programmazione, è un
elemento molto più interessante di quel che si può pensare: XOR (eXclusive OR) è utile in parecchi
casi, ma
occorre comprendere esattamente come funziona.
XOR
L' OR Esclusivo, indicato come XOR o anche come EOR o E-OR è uno degli
operatori aritmetici booleani (AND, OR, XOR, e i loro negati).
Non ha una simbologia standard, ma viene rappresentato nelle formule con
o o
A^B.
Il simbolo logico è questo:
o, secondo IEC,
Dal punto di vista logico, XOR può essere realizzato con soli NAND:
La sua tavola della verità (Truth table) è
questa:
XOR ^ Truth Table
|
Input A
|
Input B
|
A^B
|
0
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
1
|
0
|
Da un punto di vista verbale potrebbe essere espressa come "Vero se A
o B, ma non entrambi":
0
^ x = x
1 ^ x = 1
x ^ x = 0
Quale è la differenza con la funzione OR ?
La
porta OR produce
un risultato secondo
la formula:
"Se
A è 1 oppure
B è 1
(o entrambi
sono 1),
l'uscita è
1."
Questa
funzione viene
anche chiamata
OR inclusivo,
in quanto
"include"
il risultato quando
entrambi gli
ingressi sono
alti. Da questo si comprende la definizione di OR esclusivo per l' XOR,
dove questa condizione è "esclusa".
Possiamo vederlo graficamente comparando la tabella precedente con la tavola della verità di OR:
OR Truth Table
|
Input A
|
Input B
|
A^B
|
0
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
1
|
1
|
La
funzione di XOR
lavora
ovviamente anche con più ingressi e l'uscita
è VERA
(1)
se un numero
dispari di suoi
ingressi sono
a 1.
Per raccogliere
alcuni punti sull' operare di XOR:
- Qualsiasi
valore in XOR
con se stesso
da come risultato
0 (X
^ X =
0)
- XOR
con zero
non ha alcun
effetto (0
^ X
= X)
- XOR con 1 inverte
il valore
XOR nei PIC
Il set di istruzioni dei PIC include due forme di XOR:
La prima istruzione effettua l' XOR del contenuto del WREG con un "literal"
che è l' oggetto dell' istruzione stessa.
toggle movlw
b'01101111'
; maschera per il toggle del
bit2
xorlw b'00001111',f ; sul PORTC
|
dopo questa sequenza WREG conterrà b'0110000', ovvero potremmo dire
che l' applicazione dell' operatore XOR con argomento 1 ha invertito il valore
del contenuto del registro.
Quindi, una delle cose più semplici che si possono fare con XOR è quella di cambiare uno o più bit in un registro.
Ad esempio, volendo invertire lo stato dei primi due bit di un registro:
toggle2 movlw b'00000011'
; maschera per invertire i bit 1:0
; fileX contiene ad esempio b'11111111'
xorwf fileX,f ; filex contiene b'11111100' dopo l' XOR
|
Applicando l'istruzione su un port, si invertiranno i bit corrispondenti agli 1 della maschera
applicata; così se alle uscite è applicato un LED, questo si spegnerà (o
accenderà).
Questo permette di cambiare
lo stato di una uscita nel suo opposto senza la necessità di conoscerne il
valore (toggle). Ad esempio, volendo invertire lo stato del bit 2:
toggled movlw 0x02 ; maschera per il toggle del bit 2
xorwf PORTC,f ; sul PORTC
|
Possiamo
anche usare
la funzione XOR
per rilevare se
due numeri sono
gli stessi.
Se tutte le cifre binarie
(bit)
saranno
uguali,
il risultato sarà
0.
Per ogni coppia di bit diversi si otterrà un 1.
match movlw 0x0F ; bit3:0 = 1
xorwf PORTx ; verifica se i bit 3:0 di portx sono a 1
btfss STATUS,Z ; se Z flag è a 1 sono uguali
goto diversi ; altrimenti sono diversi
goto uguali
|
Un' altra possibilità di XOR è quella di scambiare il
contenuto di un file e di WREG:
movf2w xorwf file,f
xorwf file,w
xorwf file,f
|
O, ancora, scambiare il contenuto di due files senza utilizzare una
locazione di RAM intermedia:
exf2f 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'
|
XOR consente anche di copiare lo stato di uno o più bit da un registro ad
un' altro:
copy movf from_file,w
xorwf to_file,w
andlw b'xxxxxxxx' ; sostituire "x" con "1" per copiare il bit
xorwf to_file,f ; o "0" per lasciarlo inalterato
|
Posiamo utilizzare XOR anche per realizzare lookup tables che non
richiedano un return o un retlw.
Vediamo ad esempio una tabella con 6 entries:
lktab addwf pcl,f ; in out
xorlw 0Ah^00^(0Bh^01) ; W = 0 W = A
xorlw 0Bh^01^(0Ch^02) ; W = 1 W = B
xorlw 0Ch^02^(0Dh^03) ; W = 2 W = C
xorlw 0Dh^03^(0Eh^04) ; W = 3 W = D
xorlw 0Eh^04^(0Fh^05) ; W = 4 W = E
xorlw 0Fh^05 ; W = 5 W = F
|
All' ingresso
della tabella, WREG contiene un valore tra 0 e 5. Questo valore sarà sommato
al PCL e il programma salterà alla corrispondente riga della tabella.
Se il valore
in W è
0, viene
eseguita la prima linea A
^ 00 ^ (B
^ 01) e poi
tutte le seguenti: alla fine W conterrà A.
Così per le altre possibilità.
Ogni linea nella tabella si compone di vari elemnti:
- il valore da ottenere
dalla tabella (valore di W in uscita)
- il valore per la linea
successiva
- la posizione della linea
(valore di W in ingresso)
Per
capire cosa sta
succedendo, è
necessario ricordare
che:
- Qualsiasi
valore in XOR
con se stesso
rende
0
- XOR
con zero
non ha alcun
effetto
Si
tratta di un modo meno efficiente
di quello realizzabile con una tabella retlw, ma dà una idea delle possibilità dell'
operatore XOR.
Un' ulteriore possibilità è quella di generare numeri pseudo casuali:
rand movlw 01Dh ; valore iniziale (qualunque)
clrc ; clear carry per i rotate
rlf random,f ; rotate random file
btfsc status,c ; carry = 1 ?
xorwf random,w ; xor w con random, risultato in w
retlw 00
|
XOR può essere utilizzato per un semplice meccanismo di encryption.
Altro impiego classico dell' XOR riguarda la generazione e il controllo
della parità.
XOR è anche utilizzabile con vantaggio per la selezione di diverse
possibilità in base ad un indice.
|