Multi-byte Increment & Decrement
This page was originally published by me on a site called pic-projects.net.
All Microchip devices can increment and decrement an 8-bit file register in a single instruction. This article examines how a value spread over multiple file registers can be efficiently adjusted. Examples are included for 16-, 24- and 32-bit values.
Incrementing
The key to multi-byte incrementing is spotting when a value rolls over from h'ff' to h'00' as this is the trigger to increment the next most significant byte of the value. This turns out to be very easy as the INCF instruction automatically sets the Z bit in the STATUS register to reflect the result of the increment and when used in conjunction with BTFSC instruction to test the flag
; (All devices)
incf FILE0,F ; Increment 16-bits in FILE0 & FILE1
btfsc STATUS,Z
incf FILE1,F
incf FILE0,F ; Increment 24-bits in FILE0,FILE1 & FILE2
btfsc STATUS,Z
incf FILE1,F
btfsc STATUS,Z
incf FILE2,F
incf FILE0,F ; Increment 32-bits in FILE0, FILE1, FILE2 and FILE3
btfsc STATUS,Z
incf FILE1,F
btfsc STATUS,Z
incf FILE2,F
btfsc STATUS,Z
incf FILE3,F
The pattern here pretty obvious and can be extended for values of greater length. High performance processors have an INFSNZ (increment file register and skip if not zero) instruction that can be used to replace the first increment and test to shorten the sequences slightly.
; (High Performance devices)
infsnz FILE0,F ; Increment 16-bits in FILE0 & FILE1
incf FILE1,F
infsnz FILE0,F ; Increment 24-bits in FILE0,FILE1 & FILE2
incf FILE1,F
btfsc STATUS,Z
incf FILE2,F
infsnz FILE0,F ; Increment 32-bits in FILE0, FILE1, FILE2 and FILE3
incf FILE1,F
btfsc STATUS,Z
incf FILE2,F
btfsc STATUS,Z
incf FILE3,F
On high performance and enhanced mid-range devices the ADDWFC instruction offers an alternative means to adjust the value which is as fast for 32-bits and faster for larger values.
; (Enhanced Mid-Range and High Performance devices)
movlw .0 ; Load zero into WREG
bsf STATUS,C ; And set the carry
addwfc FILE0,F ; Then add to FILE0..FILE3
addwfc FILE1,F
addwfc FILE2,F
addwfc FILE3,F
Decrementing
When decrementing a value we need to know when a value will change from h'00' to h'ff' but the DECF instruction sets the Z bit in the status on a transition from h'01' to h'00' so instead we must test the value to see if it is zero before decrementing.
; (All devices)
movf FILE0,F ; Decrement 16-bits in FILE0 & FILE1
btfsc STATUS,Z
decf FILE1,F
decf FULE0,F
For longer values this pattern can only be used with the last two bytes. Lower significance bytes must be tested and a goto or branch used to skip to the corresponding DECF when a non-zero value is found.
; (All devices)
movf FILE0,F ; Decrement 24-bits in FILE0, FILE1 & FILE2
btfss STATUS,Z
goto DEC0
movf FILE1,F
btfsc STATUS,Z
decf FILE2,F
decf FILE1,F
DEC0: decf FILE0,F
movf FILE0,F ; Decrement 32-bits in FILE0, FILE1, FILE2 & FILE3
btfss STATUS,Z
goto DEC0
movf FILE1,F
btfss STATUS,Z
goto DEC1
movf FILE2,F
btfsc STATUS,Z
decf FILE3,F
decf FILE2,F
DEC1: decf FILE1,F
DEC0: decf FILE0,F
; (High performance devices)
movf FILE0,F ; Decrement 24-bits in FILE0, FILE1 & FILE2
bnz DEC0
movf FILE1,F
btfsc STATUS,Z
decf FILE2,F
decf FILE1,F
DEC0: decf FILE0,F
movf FILE0,F ; Decrement 32-bits in FILE0, FILE1, FILE2 & FILE3
bnz DEC0
movf FILE1,F
bnz DEC1
movf FILE2,F
btfsc STATUS,Z
decf FILE3,F
decf FILE2,F
DEC1: decf FILE1,F
DEC0: decf FILE0,F
On the enhanced mid-range and high performance devices the SUBFWB offers a more efficient solution.
; (Enhanced Mid-Range and High Performance devices)
movlw .0 ; Load zero into WREG
bcf STATUS,C ; And clear the carry
subfwb FILE0,F ; Then subtract from FILE0..FILE3
subfwb FILE1,F
subfwb FILE2,F
subfwb FILE3,F
© Copyright 1999-2018 Andrew John Jacobs. All rights reserved.
All trademarks and service marks are the properties of their respective owners.