Allez, courage, cela devient de plus en plus concret. On va faire un petit survol du
jeu d'instructions des PICs. On saute directement page 55 du datasheet, au chapitre 9. Et
oui, comme cet ouvrage n'est pas un manuel de référence technique, mais un
apprentissage, il faut voir les chapitres du datasheet dans le désordre.
Sur cette page, vous trouvez un petit encadré grisé qui fait allusion à deux
anciennes instructions qui ne sont plus utilisées. Nous ne nous en servirons donc pas.
Par contre, vous trouvez un tableau 9-1 qui indique comment les instructions sont codées
dans le PIC. Et la, vous voyez enfin à quoi correspondent nos 14 bits de mémoire
programme.
4.2 Les types d'instructions |
Vous constaterez donc qu'il existe 4 type d'instructions :
4.2.1 Les instructions " orientées octet "
Ce sont des instructions qui manipulent les données sous forme d'octets. Elles sont
codées de la manière suivante :
- 6 bits pour l'instruction : logique, car comme il y a 35 instructions, il faut 6
bits pour pouvoir les coder toutes.
- 1 bit de destination (d) pour indiquer si le résultat obtenu doit être conservé dans
le registre de travail de l'unité de calcul (W pour Work) ou sauvé dans l'opérande (F
pour File).
- Reste 7 bits pour encoder l'opérande (File)
Aie, premier problème, 7 bits ne donnent pas accès à la mémoire RAM totale, donc
voici ici l'explication de la division de la RAM en deux banques.
En effet, il faudra bien trouver une solution pour remplacer le bit manquant. Vous avez
dit " un bit d'un des registres ? " BRAVO, je vois que vous
avez tout compris. Il s'agit en réalité du bit RP0 du registre STATUS.
Ah, vous avez remarqué qu'il y a un RP1 ? Et oui, le 16F876 a 4 banques, ce bit
sera utilisé pour certains autres PICs que nous verrons dans la seconde partie. Vous
veillerez à laisser RP1 à 0 pour la 16F84, afin de pouvoir
" porter " votre programme sans problème vers un PIC supérieur.
4.2.2 Les instructions " orientées bits "
Ce sont des instructions destinées à manipuler directement des bits d'un registre
particulier. Elles sont codées de la manière suivante :
- 4 bits pour l'instruction (dans l'espace resté libre par les instructions
précédentes)
- 3 bits pour indiquer le numéro du bit à manipuler (bit 0 à 7 possible)
- et de nouveau 7 bits pour indiquer l'opérande.
4.2.3 Les instructions générales
Ce sont les instructions qui manipulent des données qui sont codées dans
l'instruction directement. Nous verrons ceci plus en détail lorsque nous parlerons des
modes d'adressage. Elles sont codées de la manière suivante :
- L'instruction est codée sur 6 bits
- Elle est suivie d'une valeur IMMEDIATE codée sur 8 bits (donc de 0 à 255).
4.2.4 Les sauts et appels de sous-routines
Ce sont les instructions qui provoquent une rupture dans la séquence de déroulement
du programme. Elles sont codées de la manières suivante :
- Les instructions sont codés sur 3 bits
- La destination codée sur 11 bits
Nous pouvons déjà en déduire que les sauts ne donnent accès qu'à 2K de mémoire
programme.(211). Ceci ne pose aucun problème, le 16F84
ne disposant que de 1K mots de mémoire. Pour coder une adresse de saut à l'intérieur de
la mémoire programme, il faut donc 10 bits (210 = 1024
= 1K).
Par convention, en effet, 1Kbytes correspond à 210 =
1024 octets. Ce qui explique que si vous avez 16K de mémoire, en réalité vous avez
16*1024 = 16384 bytes. Par extension, 1Mbyte = 1024 Kbytes, donc 1048576 octets.
Maintenant vous voyez pourquoi vous voyez plus que votre mémoire théorique lors du
test mémoire au démarrage de votre ordinateur. Une petite parenthèse qui n'a rien à
voir ici : les fabricants de disques durs considèrent que 1Mbytes = 1000000 bytes.
Comme Windows indique la taille en Mbytes de 1048576 bytes, cela vous explique pourquoi la
plupart de vos disques durs semblent plus petits que prévus.
4.3 Panoramique des instructions |
Je vais maintenant vous montrer comment fonctionne le tableau de la figure 9-2 page 56.
Ce tableau vous permet d'un simple regard de vous informer de la manière dont fonctionne
chaque instruction
La première colonne indique le MNEMONIQUE et les OPERANDES pour chaque opération. Les
mnémoniques sont des mots réservés (donc que vous ne pouvez utiliser que pour cet
usage) compris et interprétés par le programme d'assemblage.
Notez ici la confusion de langage commune pour le terme ASSEMBLEUR, qu'on utilise à la
fois pour indiquer le programme qui permet d'assembler le code (programme d'assemblage),
et le langage utilisé dans l'éditeur (langage d'assemblage).
Pour ne pas se compliquer la tâche, et pour employer la même dénomination que le
commun des mortels, j'adopterai le terme assembleur dans les 2 cas, même si je commets
là une faute de langage. Autant rester simple. Le contexte distinguera les deux termes.
S'il y a un doute, j'emploierais les termes explicites. En réalité, l'assembleur est le
programme qui permet de réaliser l'assemblage.
Vous allez donc trouver à cet emplacement les instructions proprement dites que vous
allez pouvoir encoder dans votre programme.
La syntaxe doit être la suivante pour l'assembleur MPLAB que nous utiliseront dès la
prochaine leçon. Nous avons dans l'ordre :
- Etiquette (facultative)
- Espace(s) ou tabulation(s),
- Mnémonique (en majuscules ou minuscules),
- Tabulation ou Espace(s)
- Opérande ou la valeur
- Virgule éventuelle de séparation
- Bit de destination W ou F ou éventuellement numéro du bit de 0 à 7 si nécessaire
- Espace(s) ou tabulation(s)
- point-virgule. (facultatif si pas de commentaire)
- Commentaire. (facultative)
Notez que le mnémonique ne peut pas se trouver en première colonne, et que tout ce
qui suit le point-virgule est ignoré de l'assembleur (donc c'est de la zone commentaire).
La première colonne est réservée pour les étiquettes (repères)
Vous disposez également de la possibilité d'insérer un ou plusieurs espace(s) ou
tabulation(s) de chaque côté de la virgule.
Voici à titre d'exemple deux lignes valides, les mots en vert sont des mots
réservés, en bleu l'instruction, ceux en jaune étant libres, le reste est du
commentaire :
Ma_ligne |
|
|
; |
Ceci est une étiquette |
|
MOVF |
STATUS,W |
; |
Charge le registre status dans le registre de travail |
La seconde colonne du tableau donne un bref descriptif de l'instruction.
La troisième colonne donne le nombre de cycles nécessaires pour exécuter
l'instruction.
Notez que toutes les instructions nécessitent un seul cycle, sauf les sauts qui en
nécessitent 2, et les opérations de test avec saut, lorsque le résultat du test
engendre le saut (instructions notées 1(2)).
La 4ème colonne donne ce qu'on appelle l' OPCODE, c'est à dire le mot
binaire que MPLAB va générer pour vous au départ du mnémonique.
Vous ne vous en servirez donc pas, mais sachez que vous pourriez programmer directement
le PIC sans passer par un assembleur, directement en construisant un fichier .hex et en
entrant les valeurs trouvées ici.
Vous devriez alors tout calculer, y compris les sauts. C'est ce que j'ai fait à mes
débuts sur un processeur 6502, car je ne disposais pas d'un assembleur. On pouvait
également utiliser cette technique pour construire des programmes auto-modifiés pour
cause de restriction mémoire.
Rassurez-vous, ces techniques appartiennent maintenant au moyen-âge de l'informatique.
Tout au plus pouvez-vous mettre en corrélation les valeurs présentes ici avec les
valeurs du tableau 9-1 à titre éducatif. Sinon, oubliez cette colonne.
La 5ème colonne est primordiale, car elle donne les INDICATEURS D'ETATS ou
STATUS FLAGS affectés (modifiés) une fois l'instruction effectuée. Nous verrons ces
indicateurs en détail, car ils constituent les clés de la programmation.
La dernière colonne renvoie à des notes en bas de page. La note 1 est très
importante, elle fait allusion à la méthode
" lecture/modification/écriture " propres aux ports d'entrées/sortie
(I/O).
Nous y reviendront au moment de la mise en oeuvre des PORTS.
La note 2 indique qu'une modification d'un timer remet à zéro son prédiviseur. Nous
y reviendront en abordant le TMR0.
La troisième note indique que si vous vous servez de l'instruction pour modifier le
compteur de programme (celui qui pointe sur la PROCHAINE instruction à exécuter), il y
aura un cycle supplémentaire. C'est logique car cela équivaut à un saut. Nous verrons
que cette technique est pratique pour aller chercher des valeurs dans une table construite
en mémoire programme.
4.4 Les indicateurs d'état |
Ces indicateurs sont indispensables pour la programmation. Il est donc absolument
nécessaire d'avoir compris leur fonctionnement (du moins pour Z et C).
Lisez donc attentivement ce qui suit. Tous les indicateurs sont des bits du registre
STATUS. Voyez le tableau page 15. Nous aborderons ici les flags Z et C. Les autres seront
traités lors de l'étude des registres.
4.4.1 L'indicateur d'état " Z "
C'est l'indicateur Zéro, il fonctionne de la manière suivante :
Si le résultat d'une opération POUR LEQUEL IL EST AFFECTE, donne un résultat égal
à 0, le flag Zéro passe à 1.
Donc, ne vous "mélangez pas les pinceaux". Dire " si Z =
1 " correspond à dire " si résultat = 0 ". Le tableau 9-2,
colonne 5 vous indique les instructions qui modifient Z.
Donc, si vous faites une addition avec ADDWF et que le résultat obtenu est 0, le bit Z
sera à 1. Si le résultat est <>0 (différent de 0), le bit Z vaudra 0. Dans
les 2 cas il est modifié.
Par contre, si vous stockez une valeur avec l'instruction MOVWF, le bit Z ne sera pas
modifié, même si la valeur vaut 0. Ces remarques sont valables pour les autres flags,
donc je n'y reviendrai pas.
4.4.2 L'indicateur d'état " C "
C'est l'indicateur pour Carry (report). Si le résultat d'une opération entraîne un
débordement, le bit C sera positionné. Il s'agit en fait du 9ème bit de
l'opération.
Petit exemple :
Si vous ajoutez |
B'11111110' |
(254) |
|
+ B'00000011' |
(3) |
Vous obtenez |
B'100000001' |
(257) donc 9 bits. |
Comme les registres du PIC ne font que 8 bits, vous obtiendrez B'00000001' (1) et C
positionné à 1 (en fait le 9ème bit, donc le bit 8,
donc 28 = 256). Donc le résultat final est de 256 + 1 =
257.
Remarquez que si vous aviez ajouté B'11111110' et B'00000010', vous auriez obtenu
B'00000000'.
Dans ce cas, vous auriez eu C à 1 ET Z à 1, ce qui signifie résultat nul, mais avec
report (donc résultat = 256).
Les autres bits du registre d'état seront vu plus loin dans ce petit ouvrage.
|