COURS 3.TXT/fr
****************************************************************** * * * COURS D'ASSEMBLEUR 68000 SUR ATARI ST * * * * par Le Féroce Lapin (from 44E) * * * * Cours numéro 3 * * * ****************************************************************** Si vous avez correctement étudié les deux premières leçons, vous devez normalement avoir un peu plus d'ordre qu'au départ, et le binaire et l'hexadécimal ne doivent plus avoir de secret pour vous. Avant de commencer je dois vous rappeler quelque chose d'essen- tiel: Il est tentant de réfléchir en chiffre alors que bien sou- vent il serait préférable de se souvenir qu'un chiffre n'est qu'une suite de bits. Ainsi imaginons un jeu dans lequel vous de- vez coder des données relatives à des personnages. En lisant ces données vous saurez de quel personnage il s'agit, et combien il lui reste de point de vie. Admettons qu'il y ait 4 personnages. Combien faut-il de bits pour compter de 0 à 3 (c'est-à-dire pour avoir 4 possibilités) seulement 2 bits. Mes personnages peuvent avoir, au maximum, 63 points de vie (de 0 à 63 car à 0 ils sont morts), il me faut donc 6 bits pour coder cette vitalité. Je peux donc avoir sur un seul byte (octet) 2 choses totalement différent- es: avec les bits 0 et 1 (le bit de droite c'est le bit 0, le bit le plus à gauche pour un byte est donc le 7) je code le type de mon personnage, et avec les bits 2 à 7 sa vitalité. Ainsi le chiffre 210 en lui même ne veut rien dire. C'est le fait de le mettre en binaire: 11010010 et de penser en regroupement de bits qui va le rendre plus clair. Séparons les 2 bits de droite: 10 ce qui fait 3 en décimal, je suis donc en présence d'un person- nage de type 3. Prélevons maintenant les 6 bits de gauche: 110100 et conver- tissons. Nous obtenons 52. Nous sommes donc en présence d'un personnage de type 3, avec 52 points de vitalité. Ceci devant maintenant être clair, passons à une explication succinte concernant la mémoire, avant d'aborder notre premier pro- gramme. STRUCTURE DE LA MEMOIRE La mémoire, c'est un tube, très fin et très long. Il nous faut distinguer 2 choses: 1) Ce qu'il y a dans le tube. 2) La distance par rapport au début du tube. ATTENTION, cette notion doit être parfaitement comprise car elle est perpétuellement source d'erreur. Grâce à la distance, nous pourrons retrouver facilement ce que nous avons mis dans le tube. Cette distance est appelé 'adresse'. Le tube a un diamètre de 1 byte (octet). Lorsque je vais parler de l'adresse $6F00 (28416 en décimal), c'est un emplacement. A cet emplacement je peux mettre un byte. Si la donnée que je veux met- tre tiens sur un word (donc 2 bytes car 1 word c'est bien 2 bytes accolés), cette donnée occupera l'adresse $6F00 et l'adresse $6F01. Imaginons que je charge une image (32000 octets) à partir de l'adresse $12C52. Je vais donc boucler 32000 fois pour déposer mon image, en augmentant à chaque fois mon adresse. Imaginons maintenant que je veuille noter cette adresse. Je vais par exemple la noter à l'adresse $6F00. Donc si je me promène le long du tube jusqu'à l'adresse $6F00 et que je regarde à ce niveau là dans le tube, j'y vois le chiffre $12C52 codé sur un long mot (les adresses sont codés sur des longs mots). Ce chiffre occupe donc 4 emplacements de tube correspondant à $6F00, $6F01, $6F02 ,$6F03. Or, que représente ce chiffre: Une adresse, celle de mon image!!!! J'espère que c'est bien clair... Un programme, c'est donc pour le 68000 une suite de lectures du contenu du tube. Il va y trouver des chiffres qu'il va interpréter comme des ordres (revoir le cours 2). Grâce à ces ordres, nous al- lons lui dire par exemple de continuer la lecture à un autre en- droit de ce tube, de revenir en arrière, de prélever le contenu du tube et d'aller le déposer autre part (toujours dans ce même tube bien sûr) etc... Pour savoir à quel endroit le 68000 est en train de lire les ordres qu'il exécute, il y a un compteur. Comme ce compteur sert pour le programme, il est appelé Program Counter, en abrégé PC. Le 68000 a un PC sur 24 bits, c'est-à-dire qu'il peut prendre des valeurs comprises entre 0 et 16777215. Comme chaque valeur du PC correspond à une adresse et qu'en face de cette adresse (donc dans le tube) on ne peut mettre qu'un octet, une machine équipée d'un 68000 peut donc travailler avec 16777215 octets, ce qui fait 16 Méga. A titre indicatif, le 80286 de chez Intel qui équipe les 'gros' compatibles PC, ne comporte qu'un PC sur 20 bits ce qui restreint son espace à 1 méga... A noter que la mémoire est destinée à recevoir des octets mais que ce que représente ces octets (texte, programme, image...) n'a strictement aucune importance. PREMIER PROGRAMME Nous allons tout de suite illustrer notre propos. Nous lançons donc GENST. Ceux qui ont un écran couleur devront le lancer en moyenne résolution, c'est préférable pour un meilleur confort de travail. Même si vous avez un 520, choisissez dans les 'préférences' de GENST (dans le menu 'Options') un chargement automatique de MONST (Load MONST 'YES') mettez un Tab Setting de 11 et auto-indent sur YES. Si MONST est déjà chargé son option dans le menu 'program' doit être disponible, sinon elle est en gris. Si c'est le cas, après avoir sauvé les préférences, quitter GENST et relancez le. Maintenant, nous allons réaliser le programme suivant: Met le chiffre $12345678 dans le registre D0 Met le chiffre $00001012 dans le registre D1 Additionne le registre D0 avec le registre D1 Tout d'abord il faut savoir que ces ordres seront mis dans le tube, et qu'il nous faudra parfois repérer ces endroits. Pour cela nous utiliserons des étiquettes, que nous poserons à côté du tube. Ces étiquettes (ou Label en Anglais) sont à inscrire tout à gauche dans notre listing alors que les instructions (ce qui est à mettre DANS le tube) seront inscrites après un espace ou mieux pour la lisibilité, après une tabulation. Ainsi notre programme devient: MOVE.L #$12345678,D0 MOVE.L #$00001012,D1 ADD.L D0,D1 Remarquer le signe # avant les chiffres. Le signe $ indique que ces chiffres sont inscrits en hexadécimal. Le signe # indique que c'est la valeur $12345678 que nous voulons mettre dans D0. Si nous avions fait MOVE.L $12345678,D0, c'est la valeur se trouvant à l'adresse $12345678 que nous aurions mis en D0. Pourquoi y a t-il .L après les MOVE et le ADD ? Nous verrons cela dans quelques minutes. Pour le moment assemblons en maintenant appuyé [ALTERNATE] puis en appuyant sur A. Normalement, tout s'est bien passé ou alors c'est que vous n'avez pas scrupuleusement recopié ce 'programme'. Maintenant, débuggons notre programme, en maintenant appuyé [ALTERNATE] et en appuyant sur D. Hop, nous nous retrouvons dans MONST qui, étant appelé à partir de GENST, a automatiquement chargé notre programme. Jetons tout d'abord un coup d'oeil à ce ramassis de chiffre... En haut nous retrouvons nos registres de données D0 à D7 ainsi que nos registres d'adresses A0 à A7 avec en prime A7'. Sous les re- gistres de données, nous voyons SR et en dessous PC. Nous pouvons remarquer que PC nous montre une adresse et la première ligne de notre programme. Le PC indique donc ce qui va être exécuté. La fenêtre du dessous (numéro 2) montre notre programme. Sur la gauche de cette fenêtre nous voyons les adresses. Symboliquement nous pouvons dire que la partie droite de cette fenêtre montre nos instructions dans le tube et que les chiffres de gauche nous indi- que l'endroit, l'adresse par rapport au début du tube. La fenêtre de droite (la 3) donne en fait la même chose que la 2, mais avec la vision du 68000. Nous avions vu dans le cours 2 que pour la machine notre suite d'ordres n'était qu'une suite de chiffres. Lorsque nous avons assemblé, l'assembleur a simplement converti ligne par ligne notre programme en chiffres. Normalement dans la fenêtre 2 vous devez voir notre programme avec en face de la première instruction, une petite flèche. Regardez l'adresse de cette instruction (c'est-à-dire le chiffre de gauche, qui indique a quel endroit dans le tube se trouve cet ordre). Avec un 1040 sous TOS 1.4, cela tourne autour de $61BF0. NOTE: Le 68000 permet à un programme de se placer n'importe où. Sur certains micro-processeurs les programmes doivent impérati- vement tous se placer au même endroit. Pour nous ce n'est pas le cas, ce qui explique que si mon programme est en $61BF0 il n'en est pas forcement de même pour vous: c'est normal. Regardez maintenant la fenêtre 3 et cherchez-y la même adresse que celle que vous avez lue dans la fenêtre 2 en face de notre pre- mière ligne de programme. Normalement si vous n'avez touché à rien cette adresse doit normalement être la première. Vous devez y voir 203C12345678. C'est ainsi que le micro-proces- seur reçoit MOVE.L #$12345678,D0!!! Retournons sur la fenêtre 2. Notons l'adresse de la seconde ligne de notre programme et soustrayons ce chiffre à l'adresse de la première ligne. Nous obtenons 6. Nous en déduisons donc que : MOVE.L #$12345678,D0 occupe 6 octets en mémoire. Faisons maintenant avancer notre programme. Pour cela maintenez enfoncé [CONTROL] et appuyez une fois sur Z. La petite flèche a sauté sur la seconde ligne, cette même ligne est maintenant indi- quée par le PC et notre registre D0 contient maintenant la valeur $12345678. MONST indique tous les chiffres en hexadécimal, vous commencez à comprendre l'intérêt de la calculatrice... Continuons en refaisant Control+Z. C'est maintenant la ligne 3 de notre programme qui est indiquée par le PC tandis que D1 s'est trouvé rempli par $00001012. Continuons avec Control+Z. L'addition entre D0 et D1 s'est effec- tuée. Comme nous l'avions vu dans le cours 2, les possibilités sont minimes car le résultat a écrasé l'ancienne valeur de D1. Pour réaliser D0+D1=D2 il aurait d'abord fallu transférer D1 dans D2 puis faire ADD.L D0,D2. Dans notre cas, D1 contient maintenant la valeur $1234668A. Notre programme n'ayant pas véritablement de fin, quittons le artificiellement en tapant Control+C. SECOND PROGRAMME Effacer le premier programme (alternate C) et tapez le suivant: MOVE.L #$12345678,D0 MOVE.W D0,D1 MOVE.B D1,D2 Nous avons vu dans Monst que D0-D7 étaient des registres assez grands. Nous avons réussi à mettre $12345678 dans D0, ce qui donne quand même 305419896 en décimal! En effet le 68000 est un micro- processeur 16/32 bits ce qui fait que ces registres ne sont pas codés sur 16 bits mais sur 32. 32 bits, cela fait un long mot (Long Word). Dans notre premier programme, nous voulions que l'instruction MOVE agisse sur tout le registre donc sur un long mot, c'est pour cela que nous avions précisé .L après le move. NOTE: Le vocabulaire est très important et demande un petit effort au début. Ainsi MOVE.L ne veut rien dire. Il convient de lire ce mnémonique (c'est ainsi que sont appelé les instructions assem- bleurs) MOVE LONG. D'ailleurs l'appellation mnémonique (qui a rapport avec la mémoire, qui sert à aider la mémoire) est à rap- procher de mnémotechnique (capable d'aider la mémoire par des moyens d'association mentale qui facilitent l'acquisition et la restitution des souvenirs /CF dictionnaire Le Robert). Autant donc lire les instructions en Anglais ce qui facilitera grandement la compréhension. Puisque notre registre D0 (comme les autres d'ailleurs) et codé sur un long mot, il contient donc 2 words côte-à-côte. Pour les distinguer nous appellerons celui de gauche word de poids fort et celui de droite word de poids faible. Chacun de ces words est lui même composé de 2 bytes, celui de gauche étant de poids fort et celui de droite de poids faible. De poids faible car les change- ment qu'il peut apporter à la totalité du nombre sont faible alors que les données de gauche (donc de poids fort) y apportent des va- riations importantes. Assemblons notre programme et débuggons. Exécutons la première ligne. Le résultat est le même que pour le premier programme: le PC indique la seconde ligne, tandis que D0 à reçu la valeur $12345678. Maintenant exécutons la seconde ligne. Que dit-elle ? MOVE.W D0,D1 C'est-à-dire déplacer le contenu de D0 pour le mettre dans D1. Mais attention, le déplacement doit se faire sur un word (précisé par .W après le move. Cela se lit MOVE WORD). Or les opérations se font toujours sur le poids faible. Le MOVE va donc prélever le word de poids faible de D0 pour le mettre dans le word de poids faible de D1. Celui-ci va donc recevoir $5678. Continuons en exécutant la troisième ligne. Celle-ci demande: MOVE.B D1,D2 (move byte d1 d2) Donc transfert du byte de poids faible de D1 vers le byte de poids faible de D2. Regarder bien les registres et les valeurs qu'ils reçoivent! Quittez maintenant le programme avec CONTROL+C TROISIEME PROGRAMME MOVE.L #$12345678,D0 MOVE.L #$AAAAAAAA,D1 MOVE.W D0,D1 SWAP D0 MOVE.W D0,D2 On efface le programme précédent, on tape celui-ci, on assemble puis on débugue. L'exécution de la première et de la seconde ligne ne doivent plus poser de problème. Nous devons obtenir D0=12345678 D1=AAAAAAAA Exécutons maintenant la troisième ligne. Il y a bien transfert du word de poids faible de D0 vers le word de poids faible de D1. Nous constatons que le word de poids fort de D1 N'EST PAS AFFECTE par ce transfert, et qu'il reste tout à fait indépendant du word de poids faible. 4ème ligne. Ce mnémonique 'SWAP' (To swap= échanger) va échanger les 16 bits de poids faible avec les 16 bits de poids fort. D0 va donc devenir 56781234. Dernière ligne. Transfert du word de poids faible de D0 (qui maintenant est 1234 et plus 5678) vers le word de poids faible de D2. Nous avons vu que D0 contenait en fait 2 données et que ces don- nées étaient totalement indépendantes. Ceci permet une grande sou- plesse de travail mais demande aussi une grande rigueur car si au lieu de faire MOVE.W D0,D1 j'avais juste commis une faute de frappe en tapant MOVE.L D0,D1 j'écrasais le word de poids fort de D1 et après je me serais étonné de trouver 1234 dans D1 à l'en- droit où je devrais encore trouver AAAA. Nous voyons tout de suite les énormes avantages de ce système. Nous n'avons à notre disposition que 8 'poches' de données (D0 à D7) mais si nous ne voulons garder que des words, nous pouvons en mettre 2 par poche, c'est-à-dire 16 en tout. De même si notre codage ne se fait que sur des bytes, c'est 32 bytes que nous pou- vons garder (4 par poche). Cela peut paraître assez évident mais par exemple sur l'Archimède, ce n'est pas possible. Sur cette ma- chine, un registre contient un long word ou rien! RESUMÉ DE VOCABULAIRE MOVE.L = move long MOVE.W = move word MOVE.B = move byte CONSEILS Prenez votre temps, relisez tranquillement ce cours et les précédents. Vous voyez ce n'est pas bien dur l'assembleur!
Back to ASM_Tutorial