★ CODING ★ AMSTRAD CPC 464 - CRÉER DE NOUVELLES INSTRUCTIONS ★ |
Nouvelles Instructions 011 |
EXEMPLES DE PROGRAMMES 8. EXEMPLE 8: TRI DE DONNÉES ALPHANUMÉRIQUES Notre approche du langage machine serait incomplète si elle ne comprenait pas une petite incursion dans le royaume des données alphanumériques. (L'étude préalable de l'Annexe V, section 2, est impéra-tive.) CALL 43830, @X$(0) X$ est le nom du tableau (qui peut être quelconque), et l'ensemble @ X$(0) pointe donc sur l'adresse du descripteur de chaîne de la première donnée du tableau (son rang est 0). Il est indispensable que nous nous arrêtions un moment sur cette notion de tableau et, pour être plus précis, sur l'organisation en mémoire des descripteurs de chaîne des éléments qui le composent. Pour n'importe quel tableau X$ (à une seule dimension), ces descripteurs de chaîne sont stockés de la manière suivante :
Les chiffres romains indiqués sur la droite ne nous serviront qu'à nommer les emplacements mémoire correspondants lors des explications. Rappelons que l'appel du programme se faisant sous le format : CALL 43830, @X$(0) Le registre IX sera pointé comme suit : Il sera nécessaire, tout au long des explications, de vous reporter à ces deux figures. Si le pointeur arrive en fin de tableau sans qu'aucune inversion ait été nécessaire, c'est donc qu'il n'y a plus d'élément à inverser et que le tableau est rangé. Pour ce qui nous concerne, précisons que, lorsqu'il sera nécessaire d'inverser deux données du tableau, nous nous contenterons en fait d'inverser leur descripteurs de chaîne respectifs. Si tout cela est bien clair, nous pouvons passer à l'étude du listing.
Le premier bloc remarquable va des lignes 1 à 8, et initialise le compteur. Nous aurons en effet besoin d'être avertis si tout le tableau est parcouru sans qu'il y ait d'inversion, signe que le programme est terminé. En réalité, il suffira d'atteindre l'avant-dernier élément du tableau, puisqu'il aura alors été comparé au suivant, c'est-à-dire au dernier. La valeur qui va nous intéresser est donc : Lignes 1 et 2 Ligne 3 Décrémentation de HL qui est maintenant pointé sur II (gardez bien à l'esprit les pointages successifs de HL). Ligne 4 Chargement du contenu de l'emplacement mémoire sur lequel est pointé HL dans le registre B. Ce dernier contient donc maintenant l'octet fort du nombre d'éléments du tableau. Lignes 5 et 6 Même principe pour charger l'octet faible dans C. Après cette ligne, BC contient le nombre d'éléments du tableau. Lignes 7 et 8 Décrémentation de BC (puisque nous voulons obtenir la valeur (nombre d'éléments –1)), puis sauvegarde par empilement. Le deuxième bloc va des lignes 9 à 23 et effectue les tâches suivantes : initialisation des pointeurs, démarrage des passes, comparaison des éléments et branchement en fonction du résultat : Lignes 9,10 et 11 Trois incrémentations successives de HL qui se retrouve pointé sur IV. Lignes 12,13 et 14 Suivant un principe analogue à celui des lignes 4, 5 et 6, l'adresse du premier élément du tableau est chargée dans DE. Lignes 15 à 19 Toujours selon le même principe, l'adresse de l'élément suivant du tableau est chargé dans BC. Ligne 20 Le contenu de l'emplacement mémoire adressé par BC est chargé dans A, qui contient donc maintenant le code ASCII de la première lettre du deuxième élément du tableau. Ligne 21 Échange de DE et HL. Ce dernier se retrouve pointé sur l'emplacement mémoire contenant le code ASCII de la première lettre du premier élément du tableau, et DE se retrouve pointé sur VIII. Ligne 22 Comparaison entre A et (HL), donc entre les deux codes ASCII. Rappelons brièvement le principe de cette comparaison (qui a déjà été étudiée dans d'autres programmes). Ligne 23 Saut à l'adresse 43869 (ligne 33) si négatif. A cette adresse commence en effet le bloc chargé de l'inversion. Voyons d'abord le cas où cette inversion n'est pas nécessaire et où le saut est ignoré : Ligne 24 L'état actuel du compteur est récupéré et chargé dans HL. Lignes 25, 26 et 27 Après une décrémentation de HL, on vérifie si son contenu est ou n'est pas égal à 0 (selon un principe déjà étudié dans le programme de pause, lignes 6, 7 et 8). Ligne 28 Retour de sous-programme si nul : si HL = 0, donc si le tableau a été parcouru jusqu'à l'avant-dernier élément sans qu'il y ait eu besoin d'inversion, le tableau est rangé correctement, et le programme est terminé. Sinon, cette instruction est ignorée. Ligne 29 Sauvegarde de la nouvelle valeur du compteur. Ligne 30 Décrémentation de DE qui, depuis la ligne 21, était pointé sur VIII et l'est maintenant sur VII. Ligne 31 Échange de HL et DE : HL est pointé sur VII. Ligne 32 Saut relatif de - 24 en ligne 12. La boucle va donc reprendre, mais le pointage dans le tableau sera décalé d'un élément (au premier tour, la comparaison se fera entre les éléments 1 et 2, au deuxième tour entre les éléments 2 et 3, au quatrième tour entre les éléments 3 et 4, etc.). Si cette boucle est exécutée (nombre d'éléments – 1) fois sans inversion, le programme retournera au BASIC en ligne 28. Mais attention : à chaque inversion, le processus doit reprendre depuis le début, et le compteur devra être en particulier réinitialisé. 1. Sauvegarder les contenus de VI, VII et VIII. Rappelons qu'au moment où le branchement vers ce bloc se fait, en ligne 23, DE était pointé sur VIII. Ligne 33 La valeur actuelle du compteur ne nous intéresse plus, puisque celui-ci devra être réinitialisé. C'est pourquoi nous l'enlevons de la pile. Lignes 34 et 35 HL est, comme DE, pointé sur VIII. Lignes 36 à 42 Elles réalisent la sauvegarde des contenus de VI, VII et VIII. Ces lignes ne nécessitent aucune explication particulière : vous connaissez toutes les instructions utilisées, et il suffit de suivre attentivement, si possible en les notant, l'état de la pile et l'évolution du contenu des registres. Une remarque cependant : vous pourrez constater que sont ui- A les deux instructions suivantes: "PUSH AF" et "POP AF" Vous n'avez jamais encore entendu parler de ce registre double AF ! En réalité, seul le contenu de A nous intéresse, et pas du tout celui de F Mais comme il est impossible d'empiler un registre simple, nous somm obligés d'empiler le registre double AF, en nous disant que A l'est par la même occasion. Lignes 43 à 46 Comme précédemment, ce bloc, qui réalise le transfert des contenus de V, IV et III dans VIII et V, s'explique de lui-même. L'instruction de transfert répétitif avec décrémentation, déjà plusieurs fois étudiée, est en particulier utilisée. Lignes 47 à 55 Là encore, rien de particuier. Ce bloc réalise évidemment le transfert des contenus initiaux de VIII, VII et VI dans V, IV et III. L'inversion des deux descripteurs de chaîne est terminée. Ligne 56 Puisqu'une inversion a eu lieu, tout le processus doit être repris : saut relatif de - 67, en ligne 1. 100 DIM TABLEAU$ (24) La ligne 100 crée un tableau de 25 éléments. |
|
Page précédente : Nouvelles Instructions 010 |
|
Page créée en 491 millisecondes et consultée 1177 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. |