Vocabulaire Xassembler pour Atmega
publication: 27 mars 2021 / mis à jour 27 mars 2021
Pour générer un code utilisable sur une carte ARDUINO, il faut préalablement compiler et assembler des primitives dans la zone TARGET. Pour ce faire, il est nécessaire de disposer, sous gForth, d'un assembleur spécifique.
Assembleur pour Atmega
gForth dispose d'un certain nombre de vocabulaires, dont un vocabulaire ASSEMBLER.
Pour voir la liste de tous les vocabulaires de gForth, il faut exécuter VOCS:
vocs libcc-types assembler esc-sequences new-locals-wl locals-types locals environment-wordlist Root Forth ok
Les vocabulaires disponibles sont affichés après vocs. On y
voit le vocabulaire assembler.
Sélection d'un vocabulaire
Pour voir le contenu d'un vocabulaire, il suffit de taper le nom de ce vocabulaire,
suivi de words:
assembler words makeflag YET BUT ?DO REPEAT AGAIN UNTIL WHILE DO BEGIN ELSE AHEAD THEN IF >offset ~cond PREFETCHT2 PREFETCHT1 PREFETCHT0 PREFETCHNTA SFENCE PSWABD PFPNACC PFNACC PF2IW PI2FW PSHUFW PSADBW PMULHUW PMOVMSKB PMINUB PMINSW PMAXUB PMAXSW PINSRW PEXTRW PAVGW PAVGB ....[CUT]... [BP+DI] [BP+SI] [BX+DI] [BX+SI] wadr wadr: bregs breg Regs finish0F 0F, finishb finish opcode, rbytes, bytes, .qa .q .da .d .wa .w .b sclear pre- .arel .64bit .rex .64now .64size .onow .osize .anow .asize seg byte? Adisp? Aimm? imm# imm disp# disp SIB# SIB ModR/M# ModR/M +rel c! allot here , >exec nonrelocate nrc (+rel >codes case? user' [A] [F] ok
L'ennui est que le contenu de ce vocabulaire assembler ne convient pas
du tout pour la génération de code destiné au processeur Atmega équipant les cartes
ARDUINO.
Comme il est hors de question de supprimer ce vocabulaire assembler
et le remplacer par notre vocabulaire assembler compatible Atmega,
on va définir un vocabulaire Xassembler.
Création du vocabulaire Xassembler
Pour créer ce nouveau vocabulaire, on va utiliser le mot vocabulary:
vocabulary Xassembler
Afin de vérifier si ce nouveau vocabulaire a bien été intégré, exécutons vocs:
vocs Xassembler libcc-types assembler esc-sequences new-locals-wl locals-types locals environment-wordlist Root Forth ok
On vérifie l'ordre de recherche des mots en tapant order:
order Forth Forth Root Forth ok
Maintenant, il faut indiquer à gForth que toutes les nouvelles définitions
doivent être intégrées à ce vocabulaire en exécutant definitions:
Xassembler definitions
On vérifie à nouveau l'ordre de recherche des mots avec order:
order Xassembler Forth Root Xassembler ok
L'ordre de recherche est lu de gauche à droite. Tout nouveau mot sera défini dans
Xassembler. Si par hasard on crée dans ce vocabulaire Xassembler
un mot déjà défini dans le vocabulaire FORTH, ce mot sera créé
dans ce vocabulaire sans altérer son homonyme dans le vocabulaire FORTH.
Dans l'article intitulé
Convertisseur
de notation infixée vers notation postfixée on crée un vocabulaire
algebra, dans mequel on définit des homonymes pour * / + -,
etc... Dans le contexte de ce vocabulaire algebra, par exemple
le mot + fonctionnera de manière différente du mot +
défini dans le vocabulaire FORTH.
Structuration des fichiers source
Voici la manière dont les fichiers sources peuvent s'organiser:
----------/ <meta>
| meta.txt
| meta_AVR328.txt
| kernel.txt
|---------------------/ <avr>
/ Xassembler.txt
/ m328def.txt
/ core.txt
/
/ <pic>
/ Xassembler.txt
/ core.txt
On a d'abord un répertoire meta dans lequel on va retrouver:
- meta.txt contenant le métacompilateur
- meta_avr328.txt qui sera une sorte de fichier "batch"
Exemple de contenu du fichier meta_avr328.txt compilé par gForth:
include meta.txt include avr/m328def.txt include avr/Xassembler.txt include avr/core.txt include kernel.txt
Des mots comme , c, sont redéfinis dans meta.txt
pour permettre la génération de code dans TARGET:
Si on souhaite générer un noyau FORTH pour un autre processeur, il suffit d'écrire un fichier meta_PIC.txt par exemple, contenant:
include meta.txt include pic/Xassembler.txt include pic/core.txt include kernel.txt
Le contenu du fichier pic/Xassembler.txt sera très différent de celui du fichier avr/Xassembler.txt.
Contenu du fichier Xassembler.txt pour Atmega
Pas question de réécrire un assembleur. Autant reprendre celui qui existe déjà dans FlashForth: FlashForth assembler for Atmega chips
Afin de rendre compatible le contenu de ce fichier avec gForth, on modifie très légèrement son contenu en mettant en début de fichier:
\ define Xassembler vocabulary Xassembler Xassembler definitions : i, , ; : flash ; : ram ; \ OFLASH constant pfl \ RAMPZV constant zfl \ value [0..3]
Le reste du code source n'est pas modifié, à l'exception de if,
qui été provisoirement neutralisé dans l'attente d'une mise au point.
L'idée finale est de remplacer ce code assembleur:
PLUS_L: .db NFA|INLINE4|1, "+" PLUS: ld t0, Y+ ld t1, Y+ add tosl, t0 adc tosh, t1 ret
par ceci dans nos primitives:
code + y+ t0 ld, y+ t1 ld, t0 tosl add, t1 tosh adc, ret, end-code
Il nous faudra donc définir les mots code et end-code dans le vocabulaire meta.
C'est ce que nous verrons dans un autre article...
