CODINGCLASSEURS WEKA ★ Comment exploiterr toutes les ressources et augmenter les performances de votre AMSTRAD CPC ★

4/2.5.1 Initiation au langage machine - V. Quelques subtilités de programmationCoding Classeurs Weka

4/2 - Assembleur Z80 : Définitions et rappels de base

4/2.5 - Cours de programmation

4/2.5.1 Initiation au langage machine

V. Quelques subtilités de programmation

Nous n'avons utilisé jusqu'à présent qu'une infime partie des possibilités du Z 80. Ajoutons donc à notre panoplie quelques outils puissants qui se révéleront indispensables dans bon nombre de situations plus délicates.

Le programme suivant permet, sur un simple CALL 40000, d'obtenir l'impression sur l'écran de cinq lignes de « $ ».

10 MEMORY 39999
20 DATA 62,36,6,200,197,245,205,93,187,241,193,16,247,201
30 FOR a=40000 TO 40013
40 READ d
50 POKE a,d
60 NEXT a
100 CALL 40000
500 STOP
1000 FOR f=1 TO 200
1010 PRINT"$";
1020 NEXT f

Les lignes 1000 à 1020, accessibles par RUN 1000, permettent d effectuer le môme travail en Basic à des fins de comparaison. Dans ce cas précis, le gain de rapidité est faible, mais il existe. Cela provient du fait que notre routine machine se sert du même programme extrait de la ROM que l'instruction PRINT du Basic : on ne gagne donc que le temps d'interprétation de la boucle FOR-NEXT.

On pourrait faire beaucoup plus rapide ân réécrivant de toutes pièces le sous-programme d'affichage, mais là n'est pas notre propos.

Le programme ci-dessous utilise plusieurs techniques de programmation qu'il est intéressant d'étudier en détail.

DEBUT  40000 LD A,36       62  36
$      40002 LD B,200       6 200
BOUCLE 40004 PUSH BC      197
       40005 PUSH AF      245
PRINT  40006 CALL BB5D    205  93 187
       40009 POP AF       241
       40010 POP BC       193

       40011 DJNZ BOUCLE   16 247
RETOUR 40013 RET          201

L'instruction CALL BB5D « appelle » un sous-programme lui-même écrit en langage machine, et implanté en mémoire à partir de l'adresse décimale 47965 (93 +(256 x 187)). Remarquons qu'en hexadécimal, 93 sécrit 5D et 187, BB...

L'adresse BB50 se situe dans la ROM Amstrad : c'est le début de la routine TXT WR CHAR, (Voir partie 4, chap. 2.7 page 12).

Toutes les routines de ce chapitre peuvent être utilisées à partir du langage machine grâce aux instructions de la famille CALL. Il faut cependant se méfier du fait que leur exécution perturbe souvent profondément le « contexte », c'est-à-dire le contenu des registres du microprocesseur.

Les instructions PUSH et POP sont précisément prévues pour remédier à ce problème : PUSH BC se charge de « mettre à l'abri » le contenu des registres B et C dans une zone mémoire sûre, directement gérée par le Z 80, la « pile machine ».

PUSH AF fait de même avec les registres A et F, tandis que les instructions POP AF et POP BC font le travail inverse : les contenus des registres sont reconstitués à partir des informations relues dans la pile. L'ordre de sortie de la piie doit cependant être inverse de celui d'entrée : ie dernier registre mis à l'abri doit être ressorti le premier, comme un journal dans une pile, d'où cette dénomination !

L'instruction DJNZ (adresse 40011 ) est tout un programme à elle seule : c'est l'une des instructions les plus puissantes du Z 80, qui fait cruellement défaut à beaucoup d'autres microprocesseurs.

A chaque fois qu'elle s'exécute, le contenu du registre B est « décrémenté ». c'est-à-dire diminué d'une unité. Tant qu'on n'arrive pas à zéro, on part exécuter une instruction située en mémoire non pas à une adresse explicitement précisée, mais à une adresse située un certain nombre d'octets avant ou après celle qui suit DJNZ : c'est ce qu'on appelle l'adressage relatif.

L'avantage majeur de ce système par rapport aux instructions du type JP est que les routines écrites de cette façon sont « relogeables » : on peut les implanter à n'importe quelle adresse mémoire sans modifications !

Essayez par exemple d'ajouter 1000 à toutes les adresses du programme page 8 (lignes 30 et 100, 10 si vous voulez) : tout fonctionnera comme avant.

Un code particulier doit cependant être utilisé pour désigner un « déplacement » qui peut être positif ou négatif, à l'aide d'un octet qui, lui, est toujours positif.

Ce code « complément à deux » est donné par la table suivante :


Codage des déplacements (offset) en « complément à deux »

Dans notre cas, c'est l'instruction de l'adresse 40013 qui doit normalement s'exécuter après DJNZ. Or, nous voulons dévier l'exécution vers l'adresse 40004, soit neuf adresses en arrière ( - 9). La table nous indique que le déplacement est représenté par l'octet de valeur décimale 247. Lors de l'écriture d'un tel programme, on ne sait pas, en général, quelle sera l'adresse de renvoi au moment où on écrit l'instruction qui le décJenchera. On utilise alors la technique des « labels » ou « étiquettes », qui permet de ne les déterminer que plus tard (comme les « assembleurs » qui travaillent en deux « passes »).

Les labels sont des noms librement choisis (mais pas trop longs tout de même) que l'on inscrit en tête des lignes de programme vers lesquelles on pense avoir à effectuer un renvoi (mais il n'y a pas d'inconvénients, au contraire, à ce que chaque ligne possède son label).

Lorsqu'une instruction de branchement (par exemple un JP ou un DJNZ) sera écrite, ce sera sous la forme JP LABEL ou DJNZ LABEL, et on remplacera l'octet (ou les deux octets) désignant l'adresse par un petit rectangle vide.

C'est exactement de cette façon que travaillent les logiciels assembleurs :

il est logique d'opérer de même lorsque l'on travaille « à la main ».

Vous en savez maintenant assez pour utiliser avec profit la documentation très complète sur le Z 80, mais ne perdez pas de vue que vous n en ôtes encore qu'au stade de l'initiation : commencez par écrire et faire fonctionner des routines de quelques dizaines d'octets, qui seront d'ailleurs capables de résoudre bon nombre de problèmes pratiques.

Augmentez petit à petit la taille de ces logiciels, mettez à contribution de nouvelles instructions, utilisez hardiment les différents registres qui sont à votre disposition, jonglez avec les « modes d'adressage » ou même avec les « interruptions » et vous deviendrez progressivement un bon programmeur de Z 80. Attendez-vous cependant à ce que vos progrès en langage machine soient plus lents et plus laborieux qu'en Basic, mais ils seront probablement aussi encore plus passionnants I

Et lorsque vous atteindrez un certain seuil d'importance de programmes, nul doute que vous vous offrirez un assembleur : votre aptitude à la programmation du Z 80 se trouvera alors considérablement secondée, et vous pourrez aller très loin...

C'est une fois le programme entièrement écrit en mnémoniques que l'on procédera à la deuxième « passe », au cours de laquelle on écrira les adresses définitives et que l'on calculera les octects manquants qui seront alors placés dans ces rectangles. Cette façon de procéder, même si elle semble lourde, fait gagner du temps surtout lorsque les modifications sont faites en cours d'écriture.

★ NOTE: 9e Complément

Page précédente : 4/2.5.1 Initiation au langage machine - IV. Vos outils de programmation

CPCrulez[Content Management System] v8.7-desktop/cache
Page créée en 133 millisecondes et consultée 81 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.