Descripción: Las siguientes rutinas nos permitirán leer y grabar la memoria de programa o código del pic de los pic16F87X  desde el propio código de programa, esto quiere decir que el propio software se puede reprogramar a si mismo según variables externas o condiciones especificas, también se puede usar para hacer un programa tipo bootloader o simplemente para usarlo como memoria de datos y de esta manera no usar una eeprom externa al pic. 
Funcionamiento: El modo de uso es similar a la lectura/escritura de una la eeprom interna del pic aunque no es necesario en este caso hacer la espera de grabación de la misma con lo que grabar la flash es mas rápido que hacer lo mismo en la eeprom.
La memoria FLASH de un pic16F87X dependiendo del modelo puede alcanzar 8K palabras de 14 bits cada una con lo que el direccionamiento será de 13 bits y el dato de 14 bits. Para direccionar tal cantidad de bits es necesario usar dos registros de 8 bits concatenados con los registros que se usaban en la eeprom (EEADR,EEDATA) para el direccionamiento y otros tantos para el dato, los registros son los siguientes y están ubicados en el banco 2.
  dato 14 bits:           Parte baja   Parte alta  
  Direccionamiento:   EEADR         EEADRH  
  Dato:                     EEDATA       EEDATAH
Los registros para configurar y inicializar  los procesos de grabación / lectura son EECON1 y EECON2, ambos ubicados en el banco 3.
 LECTURA:  Para usar la rutina de lectura de la FLASH habrá que definir las siguientes 4 variables en la memoria de datos (cuidado con el direccionamiento de banco):
ADDRL Parte baja del direccionamiento.
ADDRH Parte alta del direccionamiento.
DATAL Parte baja del dato leído.
DATAH Parte alta del dato leído.
La rutina es la siguiente:
Read_Flash  bsf  STATUS,RP1      bcf  STATUS,RP0 ;Selecciona el Banco 2     movf  ADDRL,W ;Contenido d la variable a EEADR,     movwf  EEADR ;parte baja de la direccion.     movf  ADDRH,W ;Contenido d la variable a EEADRH,     movwf  EEADRH ;parte alta de la direccion.     bsf  STATUS,RP0 ;Selecciona Banco 3     bsf  EECON1,EEPGD ;habilita acceso a la flash.     bsf  EECON1,RD ;Inicio operacion de lectura.     nop  ;se esperan dos ciclos     nop   tal como especifica el datasheet     bcf  STATUS,RP0 ;Selecciona Banco 2     movf  EEDATA,W ;DATAL = parte baja del dato leido     movwf  DATAL      movf  EEDATAH,W ;DATAH = parte alta del dato leido     movwf  DATAH      return  ;retorna de la subrutina.
 
y para usarla, una vez definidas las variables, habrá que seguir estos pasos...:
    *      Poner dato equivalente a posición de memoria a leer en las variables, ADDRL:ADDRH
    *      hacer la llamada a la subrutina con...  call  Read_Flash
    *      Una vez devuelto el control al programa principal ya tenemos las variables DATAL:DATAH llenas con el contenido de la posición de memoria leída.