★ CODING ★ PROGRAMMATION : L'ASSEMBLEUR EN DOUCEUR (6e partie) ★ |
L'assembleur en Douceur (6/x) : Les modes d'adressage (Micro-Mag) | Cours et Initiation MICROMAG |
La manipulation de valeurs en mémoire vive, via les registres du Z80, s'effectue par une action importante nommée «adressage». La terminologie en est quelque peu différente selon la méthode employée. Afin d'étudier tout ceci en détail, nous allons introduire le mnémonique «LD» destiné à adresser une valeur. Facile à retenir, il résulte de la contraction du mot anglais «Load» (charger). Après un espace, il admet deux données toujours séparées d'une virgule. La première précise l'endroit (mémoire ou registre) et la seconde, la valeur à y placer. Sachez que le langage Assembleur dispose d'un très grand nombre de mnémoniques, mais que la plupart des programmes n'en utilisent qu'une faible partie. Avant d'aborder les différents adressages, signalons que «#» précédera un nombre hexadécimal et «%» une valeur binaire (représentation de l'Assembleur ;,DEVPAC). Les nombres décimaux seront écrits tels quels. Adressage immédiat Il consiste à charger directement la valeur désirée dans un des registres, exemple:
N.B. Au risque d'alourdir le propos, signalons, pour être complet, les termes anglais que l'on rencontre parfois: MSB (Most Significant Byte), poids fort et LSB (Least Significant Byte), poids faible. Adressage registre Ici, un registre est chargé avec la valeur que contient un autre registre, exemple: LD A,B ; charge dans A Ia valeur actuellement contenue dans B (tout en conservant celle-ci dans B). Les registres doivent bien évidemment être de même capacité, donc, pas d'incongruité du genre LD A,HL. L'adressage étendu Egalement appelé direct ou absolu, il permet de stocker ou lire des valeurs en mémoire vive (RAM). Il «étend» donc le champ limité des stockage des registres, exemple:
Soulignons qu'il est logique de stocker ainsi une valeur contenue dans un double registre (clic peut atteindre 65535), puisque la capacité d'une seule adresse se limite à 255. La méthode poids fort, poids faible le permet car (255x256)+ 255 = 65535. Beaucoup moins logique est la forme de stockage inversée; raison de plus pour s'en souvenir! A noter également une nouvelle notion: un nombre entre parenthèses sera toujours relatif à une adresse. Dans notre exemple (30000) signifie à l'adresse 30000 de la RAM. Adressage indirect Il présente peu de différences avec l'adressage étendu. L'adresse n'apparaît pas directement, mais est représentée par un registre double préalablement chargé de celle-ci. HL, s'il est disponible, sera toujours préféré car les instructions qui l'emploient sont un peu plus rapides, exemple:
Observez que HL entre parenthèses est considéré comme (30000), il pointe donc une adresse. Remarquez également que par ce mode d'adressage, la valeur 8 est directement stockée à une adresse. En effet, LD (30000),8 n'est pas permis, seul LD (30000),A est correct. Fort heureusement, en cas de méprise, l'Assembleur se charge de vous rappeler à l'ordre lors de l'opération de compilation. Adressage indexé En fait, un adressage indirect qui emploie IX et IY, dits registres indexés (revoir la définition des registres):
(IX+x) dont on a souligné l'utilité pour la gestion des «tables» de données en Ram (Micro Mag n°9), permet lui aussi de fournir directement une valeur sans passer par A. Une fois de plus, il ne s'agit que de terminologies. On peut parfaitement user de tous ces modes d'adressage sans en connaître le nom. Toutefois, si d'aventure vous rencontrez au sein d'un article un verbiage du genre: «... nous allons employer une table où nous accéderons par adressage indexé», vous serez moins enclin à jeter l'ouvrage à la poubelle. Prémices Avant de nous risquer (prochainement) à quelques lignes en Assembleur, il serait bon de découvrir la première des «directives d'assemblage» rencontrée dans un programme. Le but de ces fameuses directives étant de fournir diverses indications au logiciel Assembleur, elles ne génèrent donc pas de codes machine à la compilation. Celle qui nous occupe doit être placée dès le début du programme. Il s'agit de ORG, suivi de «l'adresse d'implantation» à partir de laquelle la routine sera installée en Ram. Pourquoi la quasi-totalité des programmes réclament-ils l'adresse future d'implantation des routines? C'est en fait lié à la façon de représenter en codes machine, certains ordres de l'Assemblcur. Par exemple les «étiquettes» attribuant des noms aux sous-routines. Un nom bien choisi (exemple, «Tracé :» permet de distinguer la fonction d'une sous-routine donnée, tout en évitant de calculer et manier directement la valeur de l'adresse à laquelle elle se trouve). C'est le logiciel Assembleur qui, lors de la compilation, se charge de remplacer les étiquettes par les adresses correspondantes. Supposons que «Tracé :» commence au 50e code machine. Avec ORG 30000 précisé en début de programme, l'appel à notre sous-routine se fera en 30050. Si la fantaisie nous prend de changer l'implantation de notre programme (reloger) par un ORG 20000, l'étiquette «Tracé :» sera automatiquement remplacée par 2 0 0 5 0. Avouez que c'est plus efficace que d'avoir à tout recalculer! Déterminer une valeur pour ORG introduit d'autres réflexions, limite basse et haute par exemple. Lorsqu'on envisage d'implanter une routine en LM cohabitant avec un programme Basic, il faut placer celle-ci le plus haut possible afin de ménager une place suffisante au programme Basic. Evitez bien évidemment de squatter la mémoire vidéo, ou pire encore, les routines système, variables système, etc. Le mieux est de faire l'opération suivante: valeur de l'Himem, moins longueur de la routine en baissant encore le résultat de 100 (à moins d'un manque de place terrible). Ces emplacements supplémentaires autoriseront quelques modifications ultérieures sans avoir à modifier ORG. Pensez également à la zone destinée à accueillir des données! De plus, il faut tenir compte de la place qu'occupent ensemble l'Assembleur lui-meme, la table des symboles générés à la compilation et le programme source. A ce propos, lisez très attentivement le manuel de votre Assembleur. Une autre instruction capitale est le mnémonique RET que nous avons déjà évoqué. Son oubli est souvent lourd de conséquences. En effet, si nous avons parlé de son emploi pour clôturer une sous-routine à l'intérieur même d'une routine Assembleur, il faut savoir que c'est le RET final d'une routine qui rend la main au Basic (lors de l'appel par CALL, depuis de Basic, d'un routine en langage machine). Très bientôt, nos premiers pas...
|