Te puedo dar ejemplos de aplicacion que seria mejor con un acceso indirecto que uno directo. El mas clasico es un buffer. Comencemos por un buffer de 4 lugares. En el que recibis datos por la UART o SPI y vas guardando los valores, finalmente tenes que hacer un checksum de esos valores. Como harias con direccionamiento directo el guardar estos 4 lugares ?
Guardado
MOVF Indice, W ;El indice de mi dato
ADDWF PCL, F ; Utilizo una tabla para ir al programa donde debo guardarlo
GOTO Dato0
GOTO Dato1
GOTO Dato2
MOVF DatoUART, W
MOVWF Buffer3
CLRF Indice ; Comienzo de nuevo
RETURN
Dato0
MOVF DatoUART, W ; Tomo dato y guardo
MOVWF Buffer0
RETURN
Dato1
MOVF DatoUART, W
MOVWF Buffer1
RETURN
Dato2
MOVF DatoUART, W
MOVWF Buffer2
RETURN
Y eso es solo para guardarlo. Ahora debo sumarlos
MOVF Buffer0, W
ADDWF Buffer1, W
ADDWF Buffer2, W
ADDWF Buffer3, W
Bien, solo 4 instrucciones, bastante simple, o podria sumarlos apenas van llegando eso me ahorraria instrucciones. Ahora veamos usando acceso indirecto
Antes de comenzar cargo en el FSR los el valor de buffer0, es decir su direccion.
MOVLW low(Buffer0)
MOVWF FSR0L
MOVLW high(Buffer0)
MOVWF FSR0H
Lo que hago con eso es decir que cuando yo acceda a INDF0 , es lo mismo que acceder a la direccion de memoria que esta cargada en FSR0, en mi caso de acceder a INDF0 accederia a Buffer0. En los PIC16 normales harias eso, aca tenes una instruccion que lo hace por si solo, solo tenes que indicarle que FSR estas tratando y que hace depues
Ahora a guardar el dato:
Guardado
MOVLW d'4'
MOVWF Contador
Loop
MOVF DatoUART, W
MOVWI FSR0++
DECFSZ Contador, F
RETURN
Recargar_FSR
MOVLW low(Buffer0)
MOVWF FSR0L
MOVLW high(Buffer0)
MOVWF FSR0H
RETURN
La instruccion MOVWI, lo que hace es guardar el dato de W en la direccion que tiene FSR0 (Buffer0 ) Luego a esa direccion la incrementa por 1 apuntando ahora a Buffer1 (Al incrementar por 1 tiene en cuenta ambos registros FSR0 L y H). Entonces la proxima ves que entre va a guardar W en Buffer1 y va a apuntar a Buffer2 y asi hasta que guarde en Buffer3 y apunte a lo que sigue, ahi en ese momento me va a dar una igualdad el codigo y va a reponer el valor de FSR
Para sumar seria algo parecido
Guardado
MOVLW d'4'
MOVWF Contador
CLRF Suma_Total
CALL Recargar_FSR ;Nos aseguramos que empezamos del comienzo
Loop:
MOVIW FSR0++
ADDWF Suma_Total, F
DECFSZ Contador, F
GOTO Loop ; Todavia quedan para sumar asi que vuelve al loop
RETURN ; No queda mas nada
Nuevamente veo a que llegue al final y de ser asi salgo. Esta ves la instruccion es inversa (MOVIW ), tomo desde donde apunta el FSR0 y lo guardo en W. Y luego aumento FSR0.
Perfecto, pero para que complicarse la vida por 4 valores? Ahora supone que tenes un buffer de 32 lugares. No es nada lindo hacerlo con acceso directo, Y con acceso indirecto solo deberia cambiar esto (en ambos lugares ):
por un
Y listo funcionando

.
Solo hay incrementos ? No. Esa instruccion permite pre y post incremento y decremento
MOVWI FSR0++ ; Guarda y luego aumenta
MOVWI ++FSR0 ; Aumenta y luego guarda
MOVWI FRS0-- ; Guarda y luego decrementa
MOVWI --FRS0 ; Decrementa y luego guarda.
MOVWI k[FSR0] ; Guarda solamente, no incrementa ni decrementa., igual que hacer MOVWF INDF0
--------------------------------------------------------------------------------------------------------------
Ahora veamos un poco mas tu ejemplo.
viste el codigo que te llevo hacer un Hola no ?
Entonces hagamos algo simple para comenzar.
Vamos a crear una tabla ( no recuerdo si esta correctamente definida asi, no tuve tiempo de mirar el manual del MPASM )
Tabla:
.dt 0x00, 0xFE, 0x10, 0x10, 0xFE, 0xFC, 0x82, 0x82, 0x7C
.dt 0x00, 0xFE, 0x80, 0x80, 0x80, 0x00, 0xFC, 0x12, 0x12
.dt 0xFC, 0x00
Es un total de ... 20 datos que envias. En ves de binario los puse como hexadecimal
Tabla:
.dt 0x00, 0xFE, 0x10, 0x10, 0xFE, 0xFC, 0x82, 0x82, 0x7C
.dt 0x00, 0xFE, 0x80, 0x80, 0x80, 0x00, 0xFC, 0x12, 0x12
.dt 0xFC, 0x00
MOVLW low(Tabla) ;Cargo Valor inicial de la tabla
MOVWF FSR0L
MOVLW high(Tabla) | 0x80
MOVWF FSR0H
MOVLW d'20' ;Pongo la cantidad de datos a enviar
MOVWF Contador
Loop
MOVIW FSR0++ ; Leo la tabla guardo en W y apunto al siguiente dato
CALL DATO_SPI ; LLamo a la funcion de enviar
DEFSZ Contador, F ; Decremetno el contador y si llego a 0 salgo, sino envio el siguiente
GOTO Loop
;Fin
Y listo. con acceso indirecto accediste a la memoria de programa, tomaste todos los datos que necesitaste y listo. Pero esto seguro que lo hiciste antes.. antes hacias:
ADDWF PCL, F
RETLW 0x00
RETLW 0xFE
RETLW 0x10
RETLW 0x10
RETLW 0xFE
....
RETLW 0x00
O podias usar la misma tabla que antes.. Pero esto se complicaba si la tabla estaba entre 2 paginas.
Recorda que PCL es un registros de 8 bits y por lo tanto solo puede direccionar 256 lugares. Si querias uno mas ya se ponia mas complejo por que tenias que modificar PCLATH a la entrada y a la salida de la funcion.
Esto con el acceso indirecto que permite leer la memoria de programa no hace falta. Ya que FSR0 ( Ly H ) son 16 bits y permiten direccionar toda la memoria, si hay un incremento de 1 no es complicacion para el mismo.
EDIT: Estos codigos ninguno esta probado, asi que tal ves tengan errores, pero es para que te des una idea de como usarlos, seguro que no deben de estar MUY errados. pero si puden tener algunos errores.
Corregido el tema de usar un contador