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.