Systèmes embarqués - Instructions
Le déroulement du programme se déroule de manière séquentielle, d'une instruction à l'instruction suivante, à moins qu'une instruction de transfert de contrôle ne soit exécutée. Les différents types d'instructions de transfert de contrôle en langage assembleur comprennent les sauts conditionnels ou inconditionnels et les instructions d'appel.
Instructions de boucle et de saut
Boucle dans le 8051
La répétition d'une séquence d'instructions un certain nombre de fois est appelée loop. Une instructionDJNZ reg, labelest utilisé pour effectuer une opération de boucle. Dans cette instruction, un registre est décrémenté de 1; s'il n'est pas égal à zéro, 8051 saute à l'adresse cible référencée par l'étiquette.
Le registre est chargé avec le compteur du nombre de répétitions avant le début de la boucle. Dans cette instruction, les registres décrémentent et la décision de sauter sont combinés en une seule instruction. Les registres peuvent être de R0 à R7. Le compteur peut également être un emplacement RAM.
Exemple
Multiply 25 by 10 using the technique of repeated addition.
Solution- La multiplication peut être obtenue en ajoutant le multiplicande à plusieurs reprises, autant de fois que le multiplicateur. Par exemple,
25 * 10 = 250 (FAH)
25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 = 250
MOV A,#0 ;A = 0,clean ACC
MOV R2,#10 ; the multiplier is replaced in R2
Add A,#25 ;add the multiplicand to the ACC
AGAIN:DJNZ R2,
AGAIN:repeat until R2 = 0 (10 times)
MOV R5 , A ;save A in R5 ;R5 (FAH)
Drawback in 8051 - Action en boucle avec l'instruction DJNZ Reg labelest limité à 256 itérations seulement. Si aucun saut conditionnel n'est effectué, l'instruction suivant le saut est exécutée.
Boucle à l'intérieur d'une boucle
Lorsque nous utilisons une boucle dans une autre boucle, cela s'appelle un nested loop. Deux registres sont utilisés pour contenir le compte lorsque le nombre maximum est limité à 256. Nous utilisons donc cette méthode pour répéter l'action plus de 256 fois.
Example
Ecrire un programme dans -
- Chargez l'accumulateur avec la valeur 55H.
- Complétez l'ACC 700 fois.
Solution- Puisque 700 est supérieur à 255 (la capacité maximale de tout registre), deux registres sont utilisés pour contenir le comptage. Le code suivant montre comment utiliser deux registres, R2 et R3, pour le décompte.
MOV A,#55H ;A = 55H
NEXT: MOV R3,#10 ;R3 the outer loop counter
AGAIN:MOV R2,#70 ;R2 the inner loop counter
CPL A ;complement
Autres sauts conditionnels
Le tableau suivant répertorie les sauts conditionnels utilisés dans 8051 -
Instruction | action |
---|---|
JZ | Sauter si A = 0 |
JNZ | Sauter si A ≠ 0 |
DJNZ | Décrémenter et sauter si registre ≠ 0 |
CJNE A, données | Sauter si les données A ≠ |
CJNE reg, #data | Sauter si octet ≠ données |
JC | Sauter si CY = 1 |
JNC | Sauter si CY ≠ 1 |
JB | Sauter si bit = 1 |
JNB | Sauter si bit = 0 |
JBC | Sauter si bit = 1 et effacer le bit |
JZ (jump if A = 0)- Dans cette instruction, le contenu de l'accumulateur est vérifié. S'il est égal à zéro, le 8051 saute à l'adresse cible. L'instruction JZ ne peut être utilisée que pour l'accumulateur, elle ne s'applique à aucun autre registre.
JNZ (jump if A is not equal to 0)- Dans cette instruction, le contenu de l'accumulateur est vérifié non nul. S'il n'est pas égal à zéro, le 8051 saute à l'adresse cible.
JNC (Jump if no carry, jumps if CY = 0)- Le bit drapeau Carry dans le registre flag (ou PSW) est utilisé pour prendre la décision de sauter ou non "JNC label". Le CPU regarde l'indicateur de retenue pour voir s'il est levé (CY = 1). Si ce n'est pas le cas, la CPU commence à extraire et à exécuter des instructions à partir de l'adresse de l'étiquette. Si CY = 1, il ne sautera pas mais exécutera l'instruction suivante sous JNC.
JC (Jump if carry, jumps if CY = 1) - Si CY = 1, il saute à l'adresse cible.
JB (jump if bit is high)
JNB (jump if bit is low)
Note - Il faut noter que tous les sauts conditionnels sont des sauts courts, c'est-à-dire que l'adresse de la cible doit être comprise entre –128 et +127 octets du contenu du compteur de programme.
Instructions de saut inconditionnelles
Il y a deux sauts inconditionnels en 8051 -
LJMP (long jump)- LJMP est une instruction de 3 octets dans laquelle le premier octet représente l'opcode, et les deuxième et troisième octets représentent l'adresse 16 bits de l'emplacement cible. L'adresse cible de 2 octets est de permettre un saut vers n'importe quel emplacement mémoire de 0000 à FFFFH.
SJMP (short jump)- Il s'agit d'une instruction de 2 octets où le premier octet est l'opcode et le deuxième octet est l'adresse relative de l'emplacement cible. L'adresse relative va de 00H à FFH qui est divisée en sauts avant et arrière; c'est-à-dire entre –128 et +127 octets de mémoire par rapport à l'adresse du PC actuel (compteur de programme). En cas de saut vers l'avant, l'adresse cible peut se trouver dans un espace de 127 octets à partir du PC actuel. En cas de saut vers l'arrière, l'adresse cible peut être comprise entre –128 octets du PC actuel.
Calcul de l'adresse de saut court
Tous les sauts conditionnels (JNC, JZ et DJNZ) sont des sauts courts car ce sont des instructions sur 2 octets. Dans ces instructions, le premier octet représente l'opcode et le deuxième octet représente l'adresse relative. L'adresse cible est toujours relative à la valeur du compteur de programme. Pour calculer l'adresse cible, le deuxième octet est ajouté au PC de l'instruction immédiatement en dessous du saut. Jetez un œil au programme ci-dessous -
Line PC Op-code Mnemonic Operand
1 0000 ORG 0000
2 0000 7800 MOV R0,#003
3 0002 7455 MOV A,#55H0
4 0004 6003 JZ NEXT
5 0006 08 INC R0
6 0007 04 AGAIN: INC A
7 0008 04 INC A
8 0009 2477 NEXT: ADD A, #77h
9 000B 5005 JNC OVER
10 000D E4 CLR A
11 000E F8 MOV R0, A
12 000F F9 MOV R1, A
13 0010 FA MOV R2, A
14 0011 FB MOV R3, A
15 0012 2B OVER: ADD A, R3
16 0013 50F2 JNC AGAIN
17 0015 80FE HERE: SJMP HERE
18 0017 END
Calcul de l'adresse de la cible de saut vers l'arrière
En cas de saut vers l'avant, la valeur de déplacement est un nombre positif compris entre 0 et 127 (00 à 7F en hexadécimal). Cependant, pour un saut en arrière, le déplacement est une valeur négative de 0 à –128.
Instructions d'appel
CALL est utilisé pour appeler un sous-programme ou une méthode. Les sous-programmes sont utilisés pour effectuer des opérations ou des tâches qui doivent être effectuées fréquemment. Cela rend un programme plus structuré et économise de l'espace mémoire. Il y a deux instructions - LCALL et ACALL.
LCALL (appel long)
LCALL est une instruction de 3 octets où le premier octet représente l'opcode et les deuxième et troisième octets sont utilisés pour fournir l'adresse du sous-programme cible. LCALL peut être utilisé pour appeler des sous-programmes disponibles dans l'espace d'adressage de 64 Ko du 8051.
Pour réussir un retour au point après l'exécution du sous-programme appelé, la CPU sauvegarde l'adresse de l'instruction immédiatement sous le LCALL sur la pile. Ainsi, lorsqu'un sous-programme est appelé, la commande est transférée vers ce sous-programme, et le processeur sauvegarde le PC (compteur de programme) sur la pile et commence à extraire les instructions du nouvel emplacement. L'instruction RET (retour) renvoie le contrôle à l'appelant après avoir terminé l'exécution du sous-programme. Chaque sous-programme utilise RET comme dernière instruction.
ACALL (Appel absolu)
ACALL est une instruction de 2 octets, contrairement à LCALL qui est de 3 octets. L'adresse cible du sous-programme doit être à moins de 2 Ko car seuls 11 bits des 2 octets sont utilisés pour l'adresse. La différence entre ACALL et LCALL est que l'adresse cible pour LCALL peut être n'importe où dans l'espace d'adressage de 64 Ko du 8051, tandis que l'adresse cible de CALL est dans une plage de 2 Ko.