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.