CODINGHEBDOGICIEL ★ FORMATION A L'ASSEMBLEUR PRATIQUE LANGAGE MACHINE ★

La page pédagogique d'hebdogiciel 120: Le Pointeur SPCoding Hebdogiciel
AU COMMENCEMENT FUT LA SUITE

Où en était-on ? A cet atroce petit programme commenté d'un "devinez" écrit en charabias (non, c'était de l'assembleur). Votre cervelle a dégouliné pendant trois semaines sur le bas de la page de notre dernier cours d'assembleur ? Alors là, je ne suis pas d'accord. Il faut suivre. Surtout qu'on vous a déjà dit que c'était simple... (Solution des Jeux : le programme était destiné à vous montrer la valeur du pointeur de pile SP).

PARAGRAPHE A NE PAS LIRE

Parce qu'avec un tant soit peu de curiosité et d'envie de programmer comme un Dieu (enfin, mieux que le copain qui vient vous gonfler tous les week-ends avec ses programmes nuls), vous auriez déjà compulsé un bouquin sur les mnémoniques du Z80, et vous y auriez trouvé une dissection complète de la mnémonique "LD". Bon, on vous pardonne. Mais levez les yeux et allez zyeuter le haut de la page. Vous avez remarqué ? Il y a l'adjectif "pratique" la-haut. Ce qui signifie qu'on est complémentaire, voilà tout, complémentaire d'un bon bouquin théorique (exemple : Programmation du 280 par Rodnay Zaks chez Sybex). Notre rôle ne se limitera pas à vous apprendre à bien utiliser, sur votre machine, les mnémoniques que ce genre de bouquin vous aura présentés, mais il devrait.

LD SUPER-STAR

Alors "LD". qu'est-ce ? Il sagit du début d'un type de mnémonique très Important puisque c'est celui que vous emploierez le plus souvent En effet, LD vient de LoaD, et "load", c'est "charger" en anglais. Oui nuls charger quoi ? Des registres ou des emplacements mômoires, on l'a vu. Un programme, quai que soit son langage, est toujours un processus logique qui déplacera des données (d'un octet de RAM quelconque vers un octet de la RAM de l'écran par exempte) selon un ordre précis. Et un programme, ce n'est que cela.

SINTAX : HIC ! (NUL)

  • Un opérande, en assembleur, est un emplacement mémoire ou un registre qu'une mnémonique utilisera pour son opération. Une mnémonique peut avoir un ou deux opérandes.
  • Quand on a deux opérandes, on a un opérande source et un opérande destination. L'opérande destination est celui qui va être modifié par l'opération. L'opérande source est celui qui se contentera d'influencer le résultat.
  • On place toujours l'opérande de destination à gauche de l'opérande source et on sépare ces deux opérandes par une virgule.
  • Le mode d'adressage d'une mnémonique, abrégé "adressage", est la façon dont la mnémonique détermine l'adresse effective de ses opérandes afin d'y accéder.
  • Les parenthèses servent à préciser que l'opérande n'est pas celui qui est entre parenthèses mais que la valeur entre parenthèses est l'adresse de l'opérande effectif (des histoires de contenu et de contenant quoi ).

RÉ-EXPLICATION PAR L'EXEMPLE

LD (HL),A

Commentaires : cette mnémonique place le contenu du registre A à l'adresse mémoire précisée par HL Le contenu du registre A est l'opérande source et le contenu de l'adresse HL est l'opérande destination.

LD EN FAMILLE

Atiention, les descriptions qui vont suivre précisent l'assignation des registres a des fonctions particulières telles que nous l'avions avancé dans notre dernier cours.

  • Chargement de registre à registre :

— registre 8 bits : rien à dire, H y a des LD pour tous, soit 49 mnémoniques de ce type car le Z80 a 7 registres de travail en 8 bits (A. 8. C. D. E, H et L).
Exemple : LD A,B : effectue A - B. Puis si on dit qu'il y en a pour tout le monde c'est parce qu'on peut aussi faire LD E.C ou LD H.L par exemple, voilà.

— registres 16 bits : restreint, 3 mnémoniques. Un seul opérande destination possible : SP. Les voici :

LD SP,HL
LD SP,IX
LD SP,IY

  • Modification immédiate de la valeur d'un registre :

On parle d'adressage immédiat lorsque l'opérande source est directement mentionné. L'assemblage des mnémoniques utilisant ce mode d'adressage place l'opérande source à t'adresse suivant immédiatement le code opération.

— 8 bits : c'est bon pour les 7 registres de travail.
Exemple : LD A,&10 ; effectue A = &10.

L'opérande source ( &10 dans notre exemple ), bien évidemment, est compris entre 0 et &FF car il doit pouvoir entrer dans le registre et est donc codé sur un octet. LD A,&10 assemblé produira le code machine &3E suivi de &10. On voit que &3E, code opération, est suivi immédïatemment de &10. l'opérande source.

— 16 bits : OK pour les 3 paires de registres (HL, DE et BC) principales. mais aussi pour les registres d'index et le pointeur de pile ( IX et IY, SP ). Exemple : LD HL,&1234 ; effectue
HL = &1234 (soit H=&12. L=&34). L'opérande source est compris entre 0 et 65535 (sur deux octets quoi).

Rappel : en mémoire, l'octet bas est placé avant l'octet haut. L'assemblage de notre exemple produira tes codes machinée suivants : &21 (pour LD HL.) suivi de &34 puis &12 ( pour &1234 ).

  • Chargement d'un registre par le contenu d'une adresse mémoire :

— Avec la valeur de l'adresse source précisée directement : la destination est obligatoirement le registre A. LD A,(&1234) produit A = PEEK (&1234).

— Avec les registres BC ou DE comme pointeurs de source : la destination est aussi forcement le registre A. On a : LD A,(BC) et LD A,(DE) et c'est tout.

— Pour une destination registre 8 bits quelconque (c'est à dire B, C, D, E, H ou L, et aussi A, mais lui, il peut faire autrement, on vient de le voir) : la source doit être (HL), (IX+d) ou (IY+d), .

Exemptes : LD B,(HL) place le contenu de l'adresse pointé par HL dans te registre B. LD C,(HL), JLD E,(HL) : même chose avec C et E.

TIENS REVOILA LES REGISTRES D'INDEX

Ils sont spéciaux ceux-là. D'abord parce qu on ne doit pas toucher à IY (pour l'instant c'est comme ça puis c'est tout). Puis parce qu'on peut tour ajouter un déplacement 8 bits pour préciser l'adresse effective de l'opérande. Comment ça ? Comme ça ; LD IX,&1200 ; charge IX avec &1200. IX = &1200.
LD B,(IX+&34) ; charge B avec le contenu de l'octet d'adresse;
IX + &34. Soit B=PEEK (&1234)

Mais attention, ce déplacement est un nombre signé en complément à 2 (positif entre 0 et &7F soit 0 et 127 donc avec le bit 7 à 0, négatif entra SFF et &80 soit -1 et -128, bit 7 à 1). Là vous suivez plus, Ne vous inquiétez pas on reparlera des représentions binaires diverses. De toutes façons vous n'avez pas à tenir compte de ça pour l'indexation, vu que sous assembleur vous écrirez, par exemple, pour un déplacement de -10 octets : LD B,(ix-10). Héhéhé..

— Chargement d'un registre double par deux octets de mémoire en une seule opération : Oui ça existe (c'est presque du 16 bits) et c'est valable pour les 6 registres 16 bits (BC, DE, HL. IX, IY et SP). Exemple : LD BC,(&1000) chargera BC avec les deux octets des adresses &1000 et &1001. C'est l'équivalent Basic de C = PEEK(&1000) :B = PEEK(&1001). On voit encore une fois l'Importance de l'ordre de rangement octet faible/octet fort.

  • Chargement du contenu d'une adresse :
    • Avec un registre 8 bits comme source : C'est bien simple, le registre source est obligatoirement A. alors que fa destination peut être pointée par n'Importe quel registre double ou précisée directement . Exemples : LD (HL),A. LD (&1234),A LD (IX + &10),A.

      — Par une donnée 8 bits immédiate : Trois possibilités pour préciser la destination: (HL), (IX + d) ou (lY+d). C'est tout. Exemple : LD (HL),&12. Ça fait POKE HL,&12 et non pas HL = &12.

  • Chargement de deux octets de mémoire en une seule opération : La on est au niveau des microprocesseurs 16 bits. C'est bien pour un 8 bits. Et on peut faire ça avec n'importe quel registre double comme source . Il n'y a que l'opérande destination qui dort être précisé directement pour limiter ce genre d'instructions. Exemple : LD (&1234),DE effectue POKE &1234,E et POKE &1235,D en une seule lois C'est tout pour les LD simples. Mais on peut taire bien des choses avec cette famille d'instructions..

COMMENT ÇA, "SIMPLES", Y EN AURAIT-IL DÉS "COMPLIQUÉS" ?

Non. Compliqué, ça n'existe pas. Mais le Z80 profite aussi de LD " à répétition" . Voyons donc comment user d'une instruction à répétition face à la mémoire récalcitrante ils vont obéir ces fourmillants octets ! On va devoir d'abord préciser la sens d'opération de ces supers instructions. On s'explique. On va effectuer une série de LD. Chacun des LD d'une série de ce type enverra le contenu d'une adresse source vers une adresse destination. Entre chaque LD, on fera varier les pointeurs de source et de destination. Oui, mais va-t-on Incrémenter ces pointeurs ( les augmenter de 1 ) OU les décrémenter ( décrémenter est le contraire d'incrémenter ) ? Ceci reste de notre ressort. On le précisera par un D (pour décrément ) ou par 1 ( pour incrément ).

Ça, c'est pour le théorique, voyons maintenant le pratique. L'opérande source de ce type d instruction sera toujours pointé par le registre double HL, L'opérande destination sera pointé par DE (on peut, pour s'en rappeler, constater que D et E sont les premières lettres du mot destination). Donc, en combinant LD et I , on obtient LDI, LD et D . LDD.

Et LDI et LDD sont effectivement deux mnémoniques du Z80. Si vous nous avez suivis, vous savez déjà que LDI chargera le contenu de l'adresse DE avec le contenu de l'adresse HL, puis incrémentera les registres HL et DE.

Traduction en Basic : LDI effectue POKE DE ,PEEK

(HL): HL = HL + 1 :DE = DE + 1.

Il en est de même pour LDD, mais dans l'autre sens, LDD en Basic : POKE DE,PEEK

(HL) :HL = HL - 1 :DE = DE - 1.

ET LA RÉPÉTITION DANS TOUT ÇA?

Rien de plus simple, un petit R en plus (pour "Répétition") et tout est réglé. Nous voici avec LDIR et LDDR, mnémoniques du 290. Et naturellement, il nous faut déterminer le nombre de répétitions désiré... par te registre BC qui est le registre compteur par excellence Résumé: LDIR envoie l'octet d'adresse HL à l'adresse DE, incrémente HL et DE et recommence tant que BC n'est pas nul. On peut assimiler LDIR à la boucle Basic :

FOR I=BC TO 0 STEP-1 : POKE DE, PEEK (HL) : HL=HL+1 : DE = DE + 1 : NEXT I

LDDR à la même boucle mais avec HL - HL-1 : DE - DE-1.

Hebdogiciel n°120 , Nicolas et Zeev

★ ANNÉES: 1986
★ AUTEURS: Nicolas Et Zeev

Page précédente : La page pédagogique d'hebdogiciel 119: Registres et Adressage

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

Lien(s):
» Coding » La page pédagogique d'hebdogiciel 127: Registre F
» Coding » La page pédagogique d'hebdogiciel 146: Creation d'Une Routine
» Coding » La page pédagogique d'hebdogiciel 130
» Coding » La page pédagogique d'Hebdogiciel n°86
» Coding » La page pédagogique d'hebdogiciel 139: La Pile
» Coding » La page pédagogique d'hebdogiciel 083: Generalite sur les Routines
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 440 millisecondes et consultée 2259 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.