# Utiliser les PIC 16F et 18F/Les sous-programmes en assembleur
## Les sous-programmes

Le sous-programme est la brique de base pour la construction de programmes lisibles. Ils servent :
* à regrouper un ensemble d'instructions pour leur donner un nom explicite
* à regrouper des instructions qui font un calcul très souvent utilisé

### Les instructions de sous-programmes

Les instructions CALL et RETLW et RETURN sont pour l'appel de sous-programme.
Opérations littérales (adressage direct) et de contrôles :
| Mnémonique Opérande | Description | Cycles | 14 bits Opcode |
| CALL k | appel du sous programme k | 2 | 10 0kkk kkkk kkkk |
| GOTO k | aller à l'adresse | 2 | 10 1kkk kkkk kkkk |
| RETLW k | retour avec le littéral dans W | 2 | 11 01xx kkkk kkkk |
| RETURN | retour de sous-programme | 2 | 00 0000 0000 1000 |

### Le rôle de la pile pour les appels imbriqués

Une pile désigne une structure de données qui ressemble à une pile d'assiettes. On met les assiettes au fur et à mesure sur la pile (on appellera cette action empiler) et quand on veut en retirer une on retire celle du dessus (on appelle cette action dépiler. C'est ce que l’on appelle aussi une structure LIFO (Last in First Out).
Si l’on veut qu'un sous-programme puisse lui-même appeler un autre sous-programme il faut que les appels successifs utilisent une pile. Chaque appel (de sous-programme) empile l'adresse de retour (ou adresse de l'instruction suivante) tandis que chaque fin de sous-programme dépile cette adresse.
Avec le PIC 16F on ne peut pas abuser des sous-programmes car il n'y a que 8 niveaux d'imbrications. C'est relativement peu pour l’utilisation de compilateurs car les librairies elles-mêmes peuvent déjà en comporter quelques uns.
Il n'y a aucune instruction qui manipule explicitement la pile sur le PIC. Cela interdit aux constructeurs de compilateurs de l’utiliser pour les variables locales et les paramètres des procédures et fonctions.

## Les choix multiples

La programmation de suivant le cas faire... peut se faire de différentes manières. Nous commençons par en présenter une :
Les sous-programmes ne sont pas ici de vrais sous-programmes (car appelés avec goto et non avec call, et finissant par goto au lieu de return). D'autre part, cette technique ne traite pas le dépassement de l'index signalé par "; erreur ici". À vous d’être créatifs...

## Les tableaux en mémoire programme (lookup table en anglais)

Comme aucune instruction ne permet de lire un octet en mémoire programme, l’astuce est d’utiliser l’instruction retlw qui permet de retourner une valeur passée en argument. Écrivons donc notre tableau sous forme de retlw (voir plus haut, cela donne :
Nous pouvons ensuite utiliser PCL (poids faible du compteur programme) pour accéder à ce tableau. Si l'index d'accès au tableau est dans une variable "index" :
Donc, si on charge 1 dans W et qu’on effectue un appel « call tableau ». Le programme se branche sur la bonne ligne, le PCL est incrémenté de 1 et le programme exécute donc alors la ligne « retlw 1 ». Si l'origine du tableau est au-delà des 8 bits, par exemple :
ne pas oublier de positionner PCLATH correctement. Pour l'exemple ci-dessus, cela donne :

## L'adressage indirect du 16FXXX

Cet adressage fait appel à 2 registres, dont un est particulier, car il n’existe pas vraiment. Examinons-les donc :
Les registres FSR et INDF
INDF signifie INDirect File. C’est le fameux registre de l’adresse 0x00. Ce registre n’existe pas vraiment, ce n’est qu’un procédé d’accès particulier à FSR utilisé par le PIC® pour des raisons de facilité de construction électronique interne.
Le registre FSR est à l’adresse 0x04 dans les 2 banques. Il n’est donc pas nécessaire de changer de banque pour y accéder, quelle que soit la banque en cours d’utilisation.
Le contenu du registre FSR pointe sur une adresse en 8 bits. Or, sur certains PIC®, la zone RAM contient 4 banques (16F876). L’adresse complète est donc une adresse sur 9 bits. Le registre FSR est alors complété alors par le bit IRP du registre Status.
Les puristes peuvent se demander pourquoi ne pas écrire directement
au lieu de
C'est tout simplement parce que movf FSR,w existe mais a une autre signification, mettre le registre FSR dans w ! On a bien besoin d'un pseudo registre pour l'adressage indirect.

### Tableau en RAM

On complète l'adressage indexé de la section précédente.
avec
Nous pouvons ainsi utiliser l'adressage indexé dans les deux directions.

### Architecture complète du 16F84

Puisque cette section termine notre description du PIC 16F84 du point de vue de ses instructions, nous allons résumer ce que nous avons appris avec le schéma complet de ce microcontrôleur tel qu'on peut le trouver dans la documentation officielle.
Un certain nombre de fonctions de ce schéma seront détaillées un peu plus loin : les ports d'entrées et sorties ainsi que le timer 0.

## L'adressage indirect du 18FXXX

Le concept précédent a été étendu dans les PIC 18F pour pouvoir accéder à de plus grandes quantités de mémoires. Il y a maintenant 3 registres FSR. Puisqu’ils doivent permettre d'adresser toute la mémoire ils doivent avoir 12 bits chacun, d'où la présence de FSR2H:FSR2L, FSR1H:FSR1L et FSR0H:FSR0L. Pour compliquer un peu les choses, il y a cinq équivalent à INDF : INDFn, POSTINCn, POSTDECn, PREINCn et PLUSWn. Évidemment cette complexité est faite pour simplifier la construction des compilateurs sur cette architecture.
peut être remplacé par :
Microchip a donc ajouté une instruction pour faciliter ce mode d'adressage.
| Les structures de contrôle et l'Arithmétique en assembleur | Introduction au langage C |