
Operations on the working register, W
Q.
Can anyone explain why comf w,w will not complement W and place
the result back into W?
A.
Because W isn't a file register. The w equ 0x00 line is only used
to define a value for the "d" field of instructions. If you try to use
W as a file register you actually use the IND address, which is a
special indirect address which points to the register specified in the
FSR register.
To complement W (one's complement) you can use
xorlw 0xff
or
sublw 0xff ; subtracts W *from* 0xff
For a two's complement you can use the obvious
xorlw 0xff
addlw 0x01
sequence, or the less obvious
sublw 0x00 ; subtract W *from* 0
To increment W, use
addlw 0x01
To decrement W, use
addlw 0xff
Don't try to decrement W by
sublw 0x01
as it won't have the desired effect.
If you want to use shifts, rotates, or the swap instruction on the contents
of W, you're going to have to do something like
movwf temp
swapf temp,w
Thanks to Eric Smith for this.