Les boucles en assembleur XTENSA
publication: 14 décembre 2022 / mis à jour 14 décembre 2022
Appel à collaboration
Vous développez des montages, simples ou complexes avec ESP32 et ESP32forth.
Partagez-les ici sur ce site.
ESP32forth ne pourra se développer qu'avec la collaboration active de toutes les bonnes volontés.
Vos montages peuvent aider d'autres développeurs.
Les montages des autres développeurs peuvent vous aider.
Pour proposer un article ou un montage, cliquez ici
Fonctionnement de l'instruction LOOP en assembleur XTENSA
La boucle LOOP en assembleur XTENSA fonctionne en utilisant l'instruction LOOP pour indiquer au processeur de répéter un bloc d'instructions jusqu'à ce qu'un compteur spécifié atteigne zéro. La boucle est initialisée en définissant la valeur initiale du compteur, puis en exécutant l'instruction LOOP avec cette valeur en argument. À chaque itération de la boucle, le compteur est décrémenté de 1 jusqu'à ce qu'il atteigne zéro, moment où la boucle s'arrête.
; Initialization of the counter to 10 MOVI a0, 10 ; Beginning of the LOOP loop loop: ; Instruction(s) to repeat ... ; Decrement the counter and test the stop condition LOOP a0, loop
Ici, la boucle LOOP répète les instructions situées entre loop: et LOOP a0, boucle 10 fois, en décrémentant le compteur a0 à chaque itération. Lorsque le compteur atteint zéro, la boucle s'arrête.
Quand le processeur XTENSA rencontre l'instruction LOOP, il initialise trois registres spéciaux:
- LCOUNT ← AR[s] − 1
Le registre spécial LCOUNT est initialisé avec le contenu du registre as, ici a0 dans notre exmple, décrémenté de une unité. Quand le compteur atteint la valeur 0, l'instrution LOOP achève la boucle; - LBEG ← PC + 3
Le registre spécial LBEG contient l'adresse de début de la boucle LOOP en cours d'exécution. Cette adresse est définie par l'instruction LOOP. - LEND ← PC + (024||imm8) + 4
Le registre spécial LEND contient l'adresse de fin de la boucle LOOP en cours d'exécution. Cette adresse est définie par l'instruction LOOP.
En assembleur XTENSA, l'instruction LOOP admet deux paramètres:
LOOP as, label
label correspond à un décalage 8 bits après l'instruction LOOP. On ne peut pas répéter un code de plus de 256 octets de longueur.
Voici un code XTENSA désassemblé utilisant une boucle LOOP:
Le désassembleur indique une adresse de branchement. En réalité, le code assemblé ne contient que cet offset indiqué par le label sous forme de valeur positive 8 bits.
Gérer une boucle en assembleur XTENSA avec ESP32forth
Le langage FORTH ne sait pas résoudre une référence vers l'avant. Sauf à tatonner, il est difficile d'exploiter
l'instruction LOOP,
sans trouver une astuce.
Définition de macro-instructions de gestion de boucle
Pour utiliser facilement l'instruction LOOP,
, on va définir deux macro instructions, respectivement
For,
et Next,
dont voici le code en langage FORTH:
: For, { as n -- }
as n MOVI,
as 0 LOOP,
chere 1- to LOOP_OFFSET
;
: Next, ( -- )
chere LOOP_OFFSET - 2 -
LOOP_OFFSET [ internals ] ca! [ asm xtensa ]
;
Retrouvez toutes les macro-instructions ici:
list of useful macros for xtensa assembler
La macro instruction For,
accepte les mêmes paramètres que l'instruction LOOP,
:
as n For,
- as est le registre qui contient le nombre d'itérations de la boucle
- n est le nombre d'itérations.
Voyons tout celà dans un exemple pratique:
Utilisation des macros For, et Next,
On définit un mot myLOOP
pour tester l'instruction LOOP,
par l'intermédiaire
des macro instructions For, Next,
:
code myLOOP ( n -- n' ) a1 32 ENTRY, a8 1 MOVI, a9 4 For, \ LOOP start here a8 a8 1 ADDI, a8 arPUSH, \ push result on stack Next, RETW.N, end-code
Le registre a8 est initialisé avec la valeur 1. La boucle For, Next,
effectue une incrémentation du contenu de a8
et empile son contenu. Voici ce que donne l'exécution de MyLOOP
:
ok --> myLoop ok 2 3 4 5 -->
ATTENTION: si le nombre d'itérations est nul, le nombre d'itéraions passe à 2
Legal: site web personnel sans commerce / personal site without seling