CODING ★ MICRONEWS - Z80 ASSEMBLEUR FACILE (2eme partie) ★

Cours et initiation du Magazine Micro NewsMicro News n°07 : Z80 Assembleur Facile - Les boucles (2eme partie)

Vos cheveux se dressent dès que l'on parle de boucles en assembleur ? Voici de quoi les recoiffer élégamment.

Revenons donc à nos boucles du type for next : nous en étions resté à la boucle sur 256. Comment aller au-delà ? Les registres du Z80 qui ont des "chromosomes" communs, c'est-à-dire B et C, H et L, D et E, se marient et divorcent avec une facilité vraiment déconcertante. Puisque B ne suffit plus au delà de 256, nous allons tout simplement mettre en œuvre la paire BC, et ceci sans autre forme de procès ni précaution particulière. A partir du moment où vous nommez la paire, tout se passe comme si vous aviez affaire à un registre unique de 16 bits capable de mémoriser jusqu'à 65535 en valeur absolue.

Rappelons encore une fois que B, C, D, E, H, L désignant des registres, c'est-à-dire des organes de calcul, et non pas des variables comme en Basic.

LD BC, x : load BC,x : charger dans
BC la valeur x

Faire ceci, cela

DEC BC : Decrease BC : désincrémter
BC : faire BC=BC-1

Notez que DEC peut jouer aussi bien pour un registre pris isolément (DEC C, DEC A) que pour une paire (DEC BC, DEC DE).

Notre boucle étant du genre step-1, il nous faut à présent vérifier si BC est à 0. C'est là que les choses se corsent I Nous ne pouvons directement comparer une paire de registres à une autre paire ou à une valeur absolue.

Pire : toutes les comparaisons passent obligatoirement par A (accumulateur).

Il va donc falloir ruser et trouver une formule quelconque, si possible simple, rapide et directe. Il n'est même pas interdit de trouver autre chose qu'une comparaison : seul compte le résultat, c'est à dire vérifier si BC=0.

Il nous faut ici revenir aux jours lointains pour certains, où nous usions nos jeans à ingurgiter certaines théories relatives au calcul binaire.

Une opération logique OR s'effectue selon la table de vérité suivante :

  • premier terme égal à 0101
  • deuxième terme égal à 0111
  • résultat de l'opération OR 0111

Voici un excellent moyen pour vérifier si le premier et le second terme sont à zéro. Si nous effectuons une opération OR entre B et C, il faut et il suffit que le résultat soit 0 pour pouvoir affirmer que B (premier terme) = 0, que C (deuxième terme) = 0 et donc que la paire BC=0.

En assembleur Z80, une opération logique n'est possible qu'entre A (accumulateur) un registre, une valeur absolue ou une zone mémoire. Notez que le résultat est stocké dans A.

Bref, pour effectuer notre boucle, nous allons transférer B dans A et faire une opération logique OR entre A et C. Suivant la nature du résultat, 0 ou pas 0, le drapeau Z ou NZ est automatiquement levé. En clair ça donne :

LD A, B : load A à partir de B
OR B : opération logique OR entre A et C
JR NZ,adresse : si drapeau pas 0 remonter

La séquence suivante est absolument équivalente :

LD A,C : charger A à partir de C
OR B : opération logique OR entre A et B
JR NZ, adresse : si drapeau pas 0 remonter

Voici donc la boucle complète :

LD BC,x : initialisé la boucle à x P1 faire ceci, cela
DEC BC : faire BC=BC-1
LD A,B : transférer B dans A
OR C : opération OR entre A et C
JR NZ,P1 : ou JP,NZ P1 si la boucle est trop longue

Une remarque s'impose. La formulation ci-dessus permet de vérifier si BC (ou DE ou HL) est égal à 0. Une comparaison avec une valeur absolue autre que 0 ou avec une autre paire nécessite la mise en œuvre d'un petit programme que nous étudierons le moment venu.

Bien, me direz vous : et au delà de 65535 ? Il est facile d'écrire : "Faire ceci, faire cela". Mais précisément, "ceci, cela" correspond peut-être à des boucles, qui ont toutes besoin des registres B,C,D,E,H et L. Alors ?

On sait imbriquer des boucles. En voici un exemple qui vous fera encore toucher du doigt combien il est facile d'associer ou de dissocier les paires.

LD C,x : initialiser C à x
P1 LD B,y : initialiser B à y
P2 Faire ceci, cela

DJNZ P2 : remonter à P2 si B pas 0 Faire autre chose
DEC C : Faire C=C-1
JR NZ,P1 : remonter à P1 si C pas 0

Notez que le DEC C entraine un positionnaient automatique du drapeau Z ou NZ.

Il n'en reste pas moins que les possibilités paraissent limitées car pour l'instant nous ne comptons que 6 registres, le cas de l'accumulateur A étant réservé.

Nous allons multiplier ce chiffre par 2 : le Z80 possède 2 registres A (A et A'), 2 registres B (B et B'), etc.

Une seule instructions permet de basc. er de BC vers B'C', de DE vers D'E', de HL vers H'L'. E e se nomme EXX et n'affecte pas les contenus de BC, DE, HL.

Nous pouvons donc écrire la boucle précédente comme suit :

LD B,x : initialiser B à x
P1 EXX : passer sur l'autre jeu de registres
LD B,y : initialiser B' à y

P2 Faire ceci, cela

DJNZ P2

Faire autre chose

EXX : revenir sur le premier jeu de registres

DJNZ P1

Notez bien qu'il n'existe qu'une seule instruction de bascule pour passer d'un jeu de registres à l'autre. A vous de savoir où vous en êtes. Toutefois on ne fait appel à EXX que dans des circonstances bien précises. Le second EXX qui fait revenir au premier jeu se situe dans la plupart des cas très près du premier, car basculer BC, DE et HL peut être gênant. On préférera donc souvent trouver autre chose.

La méthode la plus courante consiste à se servir de la "pile". Voici encore une nouveauté que nous examinerons plus à fond par la suite. Cette fameuse "pile*' sert à gérer les retours de sous programme.

Accessoirement on l'utilise à d'autres fins, avec un réel succès.

LD B, x
P1 PUSH BC : empiler BC, ce qui revient à sécuriser B, et C par la même occasion
LD B, y
P2 Faire ceci, cela

DJNZ P2

Faire autre chose

POP BC : Dépiler BC ce qui revient a retrouver l'ancienne valeur de B et de C

DJNZ P1

On empilé et dépile obligatoirement une paire. Dans certains cas, cela pose problème, notamment si, comme dans notre exemple, C bouge entre le PUSH et le POP. Les manipulations avec la pile peuvent entraîner de véritables catastrophes si elles sont mai maitrisées : mettez vous face à une pile d'assiettes d'un mètre de haut et essayez de retirer celle qui se situe au bas de la pile I Comme on ne peut pas tout dire en une fois, notons déjà qu'il est indispensable de respecter la règle suivante : "premier entré, dernier sorti", ou "dernier entré, premier sorti", comme vous voulez. Mais trêve de long discours, le schéma ci-dessous résume parfaitement notre propos.

PUSH HL : empiler HL
PUSH BC : empiler BC

Partir éventuellement en sous programme à la condition expresse d'en revenir, sinon patatras.

POP BC : dépiler vers BC
POP HL : dépiler vers HL

D'autres méthodes existent pour programmer une boucle. Elles nécessitent cependant une parfaite maitrise des opérations de lecture et d'écriture en mémoire. Nous en exposerons les principes prochainement.

A.S., MICRONEWS n°7

★ REVUE: MICRONEWS
★ ANNÉE: 1988
★ AUTEUR: André Schmitt
 

Page précédente : Micro News n°06 : Z80 Assembleur Facile

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Micro News n°12 : Z80 Assembleur Facile
» Coding » Micro News n°06 : Z80 Assembleur Facile (1ere partie)
» Coding » Micro News n°08 : Z80 Assembleur Facile (3e partie)
» Coding » Micro News n°09 : Z80 Assembleur Facile (4e partie : l'organisation de la mémoire)
» Coding » Micro News n°11 : Z80 Assembleur Facile
Je participe au site:

» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 121 millisecondes et consultée 773 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.