L'Assembleur
L'assembleur utilisé est grandement (95% du code) inspiré du
code ASMPC
de J.-M FERRARD dans Les
SECRETS de la HP48G/GX
tome2.
Cet assembleur d'excellente facture était initialement écrit en Pascal et sous DOS. Ma tâche a donc consisté essentiellement à en effectuer la traduction sous environnement Win32 et C++ de sorte qu'il s'intègre au mieux dans l'OCX compilateur de HP Pascal Studio.
Voici la présentation de ses fonctonnalités:
- Chaque ligne doit être consacrée à au plus une instruction. Une ligne peut fort bien être vide. Les espaces (ou tabulations) qui débutent la ligne ou qui séparent les deux premiers mots sont ignorés.
- Dans le cas d'une instructions en un seul mot (
RTN
par exemple), la suite éventuelle de la ligne n'est pas prise en compte (on peut y placer des commentaires). Il en va de même pour tout ce qui suit le deuxième mot dans une instruction qui doit être suivie d'un argument. - Le deuxième mot d'une ligne, s'il existe, est coupé
à la première tabulation ou au premier espace rencontré
(ou bien sûr à la fin de la ligne). Cela peut être gênant
si le deuxième argument de la ligne est une chaîne de caractères
qui doit contenir un espace (instructions
LA(n)
,LC(n)
,ASC
). Dans ce cas, entourez cet argument par deux caractères""
qui seront enlevés lors du traitement. - Vous pouvez débuter une ligne par un label (étiquette)
et continuer sur cette ligne par une instruction en une ou deux parties. La
syntaxe d'une instruction pourrait donc être:
<Label> <Instruction> <Argument> <Commentaire>
...aucun de ces quatre champs n'étant obligatoire, ni ne devant débuter à une colonne précise (les champs doivent être séparés par au moins un espace ou une tabulation).
Particularités de syntaxe
Commentaires
Pour qu'une ligne entière soit considérée comme un commentaire,
faites la débuter par le signe *
. Cela permet éventuellement de
soustraire une ou plusieurs lignes à l'assemblage.
Labels
Pour déclarer un label, faites débuter la ligne par le caractère
:
suivi immédiatement par le nom du label. Pour le nom du label, il n'y
a aucune contrainte sur les caractères à utiliser.
Branchements
Tous les branchements relatifs GOTO
, GOC
, GONC
, GOSUB
,
GOSUBL
, GOYES
, GOLONG
doivent s'effectuer vers un label. Pour les branchements absolus, vous pouvez
utiliser des adresses sous forme héxadécimale (#679B ou $679B
par exemple) ou employer des variables locales.
Variables locales
Vous pouvez créer des variables locales, dont la durée de vie
va de la ligne où elles sont déclarées à la fin
du fichier. Deux variables ne peuvent porter le même nom. Pour déclarer
une variable locale, faites débuter la ligne par le symbole =
suivi immédiatement
du nom de cette variable. Le contenu de cette variable est le deuxième
mot de la ligne.
=VARIABLE 123
D0=(2) VARIABLE
Instructions particulières
Instruction HEX
Elle permet d'incorporer au code-objet un certain nombre (au plus 255) de caractères héxadécimaux. Une erreur est évidemment détectée si l'un au moins de ces caractères n'est pas dans l'ensemble '0'..'9','A'..'F'.
HEX 4F2AA80C
Instruction ASC
Elle permet d'incorporer une chaîne de caractères au code-objet
(au plus 127 caractères). Chaque caractère sera codé selon
son code ascii, sur deux quartets. Si cette chaîne doit contenir des espaces
ou tabulations, entrourez la de deux caractères ""
. Ces deux caractères
ne seront pas pris en compte.
ASC ESSAI
ASC "NOUVEL ESSAI"
Instruction NUL
Elle permet d'incorporer un certain nombre de quartets nuls dans le code objet. Le nombre de ces quartets est spécifié par le deuxième argument de l'expression. Exemple:
NULL #100
(256 quartets nuls)
Instructions REL2, REL3, REL4, REL5
Elles doivent être suivies d'un label (déjà déclaré ou non), et génèrent le décalage (négatif ou positif) entre l'adresse en cours et l'adresse du label (adresses relatives au code-objet).
Instructions LC(n) et LA(n)
L'entier n peut être compris entre 1 et 16. L'argument peut être
un entier, une variable de contenu entier, ou une chaîne de caractères
encadrés par ""
(qui seront ignorés).
Instructions LAREL et LCREL
Elles doivent être suivies d'un label désignant un autre point du programme. Leur rôle est de charger, dans le registre A ou C (sur 5 quartets) l'offset (déplacement) calculé entre l'adresse où débute l'instruction et l'adresse correspondant au label.
adr1 :Label
A=DAT1 A
DAT0=A A
D0=D0+ 5
...
adr2 LCREL Label
Ici le registre C est chargé avec la valeur adr1-adr2
. En fait tout
se passe comme si on avait l'instruction LC(5) adr1-adr2
. Le contenu
du registre P est important car il indique à partir de laquelle les 5
quartets sont écrits dans le registre.
Instructions LAABS et LCABS
Elles doivent être suivies d'un label désignant un autre point du programme. Leur rôle est de charger, dans le registre A ou C (champ A) l'adresse absolue correspondant au label. Le code-objet en cours d'exécution n'a aucune raison de se trouver à une adresse fixée (si le code est contenu dans une variable, vous pouvez par exemple déplacer cette variable dans un menu VARS).
Il est cependant parfois utile de connaître
l'adresse où, au moment présent, se trouve telle ou telle partie
du code (il s'agit souvent de pointer sur des données à l'intérieur
de ce code). Les instructions LAABS
et LCABS
sont des macro-instructions
puisqu'elles génèrent un code correspondant à plusieurs
instructions successives. L'instruction LAABS Loop
est traduite en:
P=0 Met le registre P à 0 pour LAREL
RSTK=C Sauvegarde C:A
C=PC L'adresse de l'instruction LAREL va dans C:A
LAREL Loop A:A=adresse de "Loop" - adresse de "LAREL"
A=C+A A A:A=adresse de "Loop"
C=RSTK Récupère C:A
Vous remarquez donc que l'adresse absolue de Loop
est calculée
au moment de l'exécution et que le contenu de C est inchangé par
cette opération. Par contre P est remis à zéro pour assurer
le fonctionnement correct de l'ensemble.
Instruction RESSOURCE
Elle permet d'insérer les graphiques contenus dans une ressource. L'argument de cette instruction est le nom du fichier de ressources. Son effet est uniquement d'insérer toutes les données graphiques les unes à la suite des autres.