Les branchements en assembleur XTENSA
publication: 14 décembre 2022 / mis à jour 16 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
Les instructions de branchement en assembleur XTENSA
L'assembleur XTENSA dans le vocabulaire xtensa
dispose de plusieurs types d'instructions de branchement:
- les branchements utilisant des flags booléens définis dans le registre spécial BR:
BF, BT,
- les branchements effectuant des tests sur les registres:
BALL, BANY, BBC, BBS, BEQ, BGE, BLT, BNE, BNONE,
C'est cette seconde catégorie de branchements qui nous intéresse.
Définition de macros de branchement
L'assembleur xtensa
de ESP32forth ne dispose pas de mécanisme de gestion de labels comme c'est le cas
pour un assembleur classique. Pour être efficace, la gestion de labels doit fonctionner en plusieurs étapes s'il faut résoudre
des branchements vers l'avant. Ceci est incompatible avec le fonctionnement du langage FORTH qui compile ou assemble en une seule passe.
On lève cette difficulté en définissant deux macros instructions, If,
et Then,
, qui vont gérer ces branchements vers
l'avant:
: If, ( -- BRANCH_OFFSET )
chere 1-
;
: Then, { BRANCH_OFFSET -- }
chere BRANCH_OFFSET - 2 -
BRANCH_OFFSET [ internals ] ca! [ asm xtensa ]
;
La macro instruction doit être précédé d'une autre macro instruction. Pour notre premier test, on définit la macro
<,
qui assemblera un branchement non résolu:
: <, ( as at -- )
0 BGE,
;
Utilisation de ces macros dans notre premier exemple:
code my< ( n1 n2 -- fl ) \ fl=1 if n1 < n2 a1 32 ENTRY, a8 arPOP, \ a8 = n2 a9 arPOP, \ a9 = n1 a7 0 MOVI, \ a7 = 1 a8 a9 <, If, a7 1 MOVI, \ a7 = 0 Then, a7 arPUSH, RETW.N, end-code
Syntaxe des macro instructions de branchement
Dans notre exemple, nous avons utilisé la macro instruction <,
qui est associé à l'instruction de
branchement BGE,
et dont la signification est: Branch if Greater Than or Equal
(Brachement si plus grand ou égal).
Normalement, il faudrait traduire par >=
. Pourquoi a-t-on utilisé <
?
C'est parce que notre macro instruction If, .... Then,
a une logique inverse à celle du branchement à effectuer.
Le code placé entre If, .... Then,
s'exécutera si la condition requise n'est pas valide.
Voici le tableau qui récapitule cette logique inversée expliquant le choix du nom de ces macro instructions utilisées avant
If, .... Then,
:
XTENSA branch instruction | Macro | ||
---|---|---|---|
BEQ | Branch if Equal | AR[s] = AR[t] | <>, |
BGE | Branch if Greater Than or Equal | AR[s] ≥ AR[t] | <, |
BLT | Branch if Less Than | AR[s] < AR[t] | >=, |
BNE | Branch if Not Equal | AR[s] ≠ AR[t] | =, |
Revenons à notre exemple d'assemblage my<
. Voici ce que donne l'exécution de ce mot:
10 20 my< . \ display: 1 20 20 my< . \ display: 0 20 10 my< . \ display: 0 -5 35 my< . \ display: 1 -10 -3 my< . \ display: 1 -3 -10 my< . \ display: 0
Nous constatons que cette logique inversée est respectée.
Une fois cette logique comprise, on peut définir une nouvelle macro-instruction >=,
:
: >=, ( as at -- )
0 BLT,
;
Et test de cette macro-instruction:
code my>= ( n1 n2 -- fl ) \ fl=1 if n1 < n2 a1 32 ENTRY, a8 arPOP, \ a8 = n2 a9 arPOP, \ a9 = n1 a7 0 MOVI, \ a7 = 1 a8 a9 >=, If, a7 1 MOVI, \ a7 = 0 Then, a7 arPUSH, RETW.N, end-code 10 20 my>= . \ display: 0 20 20 my>= . \ display: 1 20 10 my>= . \ display: 1 -5 35 my>= . \ display: 0 -10 -3 my>= . \ display: 0 -3 -10 my>= . \ display: 1
Legal: site web personnel sans commerce / personal site without seling