2001 Microchip Technology Inc.
Advance Information
DS39541A-page 59
PIC18C601/801
4.12
Indirect Addressing, INDF and
FSR Registers
Indirect addressing is a mode of addressing data mem-
ory, where the data memory address in the instruction
is not fixed. A SFR register is used as a pointer to the
data memory location that is to be read or written. Since
this pointer is in RAM, the contents can be modified by
the program. This can be useful for data tables in the
shows the operation of indirect addressing. This shows
the moving of the value to the data memory address
specified by the value of the FSR register.
Indirect addressing is possible by using one of the
INDFn (0
≤ n ≤ 2) registers. Any instruction using the
INDFn register actually accesses the register indicated
by the File Select Register, FSRn (0
≤ n ≤ 2). Reading
the INDFn register itself indirectly (FSRn = ’0’), will read
00h. Writing to the INDFn register indirectly, results in a
no-operation. The FSRn register contains a 12-bit
to clear the RAM in Bank 1 (locations 100h-1FFh) in a
minimum number of instructions.
EXAMPLE 4-6:
HOW TO CLEAR RAM
(BANK 1) USING
INDIRECT ADDRESSING
There are three indirect addressing registers. To
address the entire data memory space (4096 bytes),
these registers are 12-bit wide. To store the 12-bits of
addressing
information,
two
8-bit
registers
are
required. These indirect addressing registers are:
1.
FSR0: composed of FSR0H:FSR0L
2.
FSR1: composed of FSR1H:FSR1L
3.
FSR2: composed of FSR2H:FSR2L
In addition, there are registers INDF0, INDF1 and
INDF2, which are not physically implemented. Reading
or writing to these registers activates indirect address-
ing, with the value in the corresponding FSR register
being the address of the data.
If an instruction writes a value to INDF0, the value will
be written to the address indicated by FSR0H:FSR0L.
A read from INDF1 reads the data from the address
indicated by FSR1H:FSR1L. INDFn can be used in
code anywhere an operand can be used.
If INDF0, INDF1, or INDF2 are read indirectly via an
FSR, all ’0’s are read (zero bit is set). Similarly, if
INDF0, INDF1, or INDF2 are written to indirectly, the
operation will be equivalent to a NOP instruction and the
STATUS bits are not affected.
4.12.1
INDIRECT ADDRESSING
OPERATION
Each FSR register has an INDF register associated
with it, plus four additional register addresses. Perform-
ing an operation on one of these five registers deter-
mines how the FSR will be modified during indirect
addressing.
When data access is done to one of the five INDFn
locations, the address selected will configure the FSRn
register to:
Do nothing to FSRn after an indirect access (no
change) - INDFn
Auto-decrement FSRn after an indirect access
(post-decrement) - POSTDECn
Auto-increment FSRn after an indirect access
(post-increment) - POSTINCn
Auto-increment FSRn before an indirect access
(pre-increment) - PREINCn
Use the value in the WREG register as an offset
to FSRn. Do not modify the value of the WREG or
the FSRn register after an indirect access (no
change) - PLUSWn
When using the auto-increment or auto-decrement fea-
tures, the effect on the FSR is not reflected in the
STATUS register. For example, if the indirect address
causes the FSR to equal '0', the Z bit will not be set.
Incrementing or decrementing an FSR affects all 12
bits. That is, when FSRnL overflows from an increment,
FSRnH will be incremented automatically.
Adding these features allows the FSRn to be used as a
software stack pointer, in addition to its uses for table
operations in data memory.
Each FSR has an address associated with it that per-
forms an indexed indirect access. When a data access
to this INDFn location (PLUSWn) occurs, the FSRn is
configured to add the 2’s complement value in the
WREG register and the value in FSR to form the
address before an indirect access. The FSR value is
not changed.
If an indirect addressing operation is done where the
target address is an FSRnH or FSRnL register, the
write operation will dominate over the pre- or post-
increment/decrement functions.
LFSR
FSR0, 100h
;
NEXTCLRF
POSTINC0
; Clear INDF
; register
; & inc pointer
BTFSS
FSR0H, 1
; All done
; with Bank1?
BRA
NEXT
; NO, clear next
CONTINUE;
:
; YES, continue