Autres articles / Other articles

Les branchements en assembleur XTENSA

publication: 14 décembre 2022 / mis à jour 16 décembre 2022

Read this page in english

 

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:

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 instructionMacro
BEQBranch if EqualAR[s] = AR[t]<>,
BGEBranch if Greater Than or EqualAR[s] ≥ AR[t]<,
BLTBranch if Less ThanAR[s] < AR[t]>=,
BNEBranch if Not EqualAR[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