Autres articles / Other articles

Accés à la mémoire en assembleur XTENSA

publication: 8 décembre 2022 / mis à jour 11 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


Utilisation d'un désassembleur en ligne

Avant d'aller plus loin avec notre assembleur XTENSA depuis ESP32forth, signalons l'existence d'un outil très pratique pour vérifier le code assemblé. Cet outil est disponible ici:

https://onlinedisassembler.com/odaweb/

Ce désassembleur permet de désassembler le code binaire depuis son format hexadécimal. Exemple:

code myL32R 
a1 32           ENTRY,  
a8 $FFFE        L32R, 
a8          arPUSH, 
                RETW.N,  
end-code 
 
hex 
val01 
' myL32R cell+ @ 5 disasm 
' myL32R cell+ @ 20 dump 

Voici ce que donne le désassemblage de ce code depuis ESP32forth:

40091B64  --  a1 20 ENTRY,              -- 004136
40091B67  --  a8 FFFE L32R,             -- FFFE81
40091B6A  --  a2 a2 4 ADDI,             -- 04C222
40091B6D  --  a8 a2 0 S32I.N,           -- 0289
40091B6F  --  RETW.N,           -- F01D

Et le DUMP mémoire de ce même code. La partie qui nous intéresse est ici en rouge:

--addr---  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  ------chars-----
4009-1B60  21 43 65 87 36 41 00 81 FE FF 22 C2 04 89 02 1D  !Ce.6A....".....
4009-1B70  F0 BB EF 4B 0A A6 89 59 35 C8 F5 94 42 C3 26 FD  ...K...Y5...B.&.
4009-1B80  A2 B4 DF 86 BE 13 5A C8 F3 21 60 24 67 B5 EA 92  ......Z..!`$g...

Copions et collons ce code hexadécimal dans le désassembleur en ligne. Voici ce que donne le désassemblage en ligne:

Ce désassemblage permet:

Accéder à une adresse mémoire

Le processeur XTENSA est très puissant. C'est un processeur capable de traiter les accès mémoitre en 32 bits. Mais il est difficile d'insérer une valeur littérale 32 bits dans un registre d'adresse. Parmis les méthodes possibles, commençons par un accès mémoire via la pile de données:

variable myVarTest 
10 myVarTest ! 
 
code __my@ ( addr -- n ) 
    a1 32       ENTRY, 
    a8      arPOP, 
    a9 a8 0     L32I.N, 
    a9      arPUSH, 
                RETW.N,  
end-code 

Exemple d'utilisation du mot __my@:

myVarTest __my@ .   \ display 10 

Cette méthode a comme principal inconvénient de faire transiter une valeur 32 bits par la pile de données.

Définition de constantes 32 bits pour l'assembleur XTENSA

Rappelons qu'il n'existe aucune instruction XTENSA permettant de charger une valeur littérale 32 bits dans un registre d'adressage. Seule l'instruction L32R, permet de charger une valeur 32 bits dans un registre d'adresse en indiquant une adresse relative.

L'instruction L32R, charge le registre at avec le contenu de l'adresse mémoire pointée par PC-offset. Cet offset se réfère toujours à une adresse mémoire définie avant PC (Program Counter). L'offset est multiplié par quatre et décrémenté de PC. Exemple:

a8 $fffe        L32R, 

Ici, le décalage est calculé à partir de PC+(-2x4). La valeur de décalage est une valeur immédiate comprise dans l'intervalle [$0001..$FFFF] en hexadécimal. Ceci autorise l'adresse de n'importe quelle adresse mémoire comprise dans l'intervalle PC-262141 à PC-4.

L'assembleur conventionnel XTENSa prend comme paramètre pour l'instruction L32R un label pointant sur une adresse mémoire. Ce n'est pas le cas pour notre assembleur XTENSA sous ESP32forth qui admet comme valeur immédiate un offset précalculé.

Voici une manière élégante de définir des labels compatibles avec notre assembleur XTENSA sous ESP32forth:

forth 
DEFINED? code invert [IF] xtensa-assembler [THEN] 
 
asm definitions 
: defForL32R:  ( comp: n --  | exec: -- addr ) 
    create 
        chere , 
        code4, 
    does> 
        @   chere - 4 / 
  ; 

Notre mot defForL32R: étend le vocabulaire asm et permet maintenant de définir une constante accessible par son adresse mémoire:

\ example:
$87654321 defForL32R: val01 

Ici, on définit un pointeur val01 dont le contenu pointe vers l'adresse mémoire contenant la valeur hexadécimale $87654321. Voici comment utiliser ce pointeur avec l'instruction L32R,:

forth definitions 
asm xtensa 
 
$87654321 defForL32R: val01 
 
code myL32R 
    a1 32           ENTRY,  
    a8 val01        L32R, 
    a8          arPUSH, 
                    RETW.N,  
end-code 

L'exécution de myL32R dépose la valeur hexadécimale 87654321 sur la pile de données FORTH.


Legal: site web personnel sans commerce / personal site without seling