ASSEMBLEUR

 

 
COURS D'ASM 68000
(par le Féroce Lapin)

retour au VOLUME 1


******************************************************************
*                                                                *
*             COURS D'ASSEMBLEUR 68000 SUR ATARI ST              *
*                                                                *
*                 par Le Féroce Lapin (from 44E)                 *
*                                                                *
*                         Cours numéro 6                         *
*                                                                *
******************************************************************

LA  PILE    Nous  avons déjà utilisé la notion de 'tube' en ce qui
concerne la mémoire. Nous pouvons y stocker différentes choses, et
si nous nous rappelons l'adresse, nous pouvons revenir plus tard à
cet endroit pour y récupérer ce que nous y avions déposé.

Essayez avec ce petit programme:

       MOVE.L     #$12345678,D0
       MOVE.L     D0,$493E0
       MOVE.L     #0,D0
       MOVE.L     $493E0,D0

Assemblez  puis  passez  sous  MONST. Avancez en pas à pas. D0 est
d'abord rempli avec $12345678, puis le contenu de D0 est transféré
à l'adresse $493E0. Notez bien qu'il n'y a pas de # devant $493E0,
afin d'indiquer qu'il s'agit bien d'une adresse. Cette ligne étant
exécutée, activez  la fenêtre 3 ([Alternate+3]) et placez le début
de  celle-ci sur l'adresse $493E0 ([Alternate+A] puis tapez 493E0)
Vous  voyez  bien  12345678 à  cet endroit dans le 'tube'. Si j'ai
choisit  cette  adresse c'est parce qu'elle se situe à 300 Kilo du
début  de la mémoire. Elle est donc accessible même sur un 520, et
elle  est  suffisamment éloignée pour ne pas se trouver dans GENST
ou MONST. En effet il n'y a qu'un 'tube' mémoire! Nous sommes donc
en  train d'écrire dans la mémoire alors qu'une partie de celle-ci
est occupée par GENST et MONST! Ecrire à l'intérieur des zones oc-
cupées  par  ces  programmes  est possible, ce qui entraînera très
certainement quelques plantages de ceux-ci!

Continuons  en  pas  à pas, nous mettons D0 à 0 puis le contenu de
l'adresse $493E0 (sans #) est remis dans D0.

La  pile, c'est  une partie de ce tube, mais que nous allons gérer
d'une  manière  un peu différente. En effet, au lieu de placer les
données dans le tube et de noter leurs adresses, nous allons cette
fois-ci les empiler et pour les récupérer, les dépiler. L'avantage
c'est  le  gain  de  temps  (pas  la peine de se demander à quelle
adresse  on  a  stocké  les données) et un gain de place (si c'est
pour  stocker temporairement des données, inutile de conserver une
portion de 'tube' juste pour ça).

Par  contre  l'inconvénient  c'est que la gestion doit être rigou-
reuse. Imaginons  que  j'empile  un premier chiffre puis 10 autres
par  dessus. Ensuite  je  dépile, mais  erreur  de  ma part, je ne
dépile  que  9 chiffres! Quand  je  dépilerai  une  fois  de plus,
croyant  retrouver  le  premier  chiffre empilé, je récupérerai en
fait le premier de la série de 10.

Nous  en concluons 2 choses: d'abord que la pile est un moyen sim-
ple  pour  sauvegarder  des  données, mais  ensuite  que c'est une
source de désagrément potentiel, tel que certains programmeurs hé-
site  à s'en servir. C'est généralement à cause d'un manque de ri-
gueur ce qui, je l'espère ne vous arrivera pas.

Une autre remarque: le dernier élément placé sur la pile sera tou-
jours  le premier à en sortir. C'est bien le même principe que ce-
lui  d'une  pile  d'assiettes: Regardez chez vous, il y a sûrement
une énorme pile d'assiettes, mais par le simple fait que le range-
ment  après  le lavage se fait par empilage et que mettre la table
se  fait par dépilage, vous mangez en fait toujours dans les mêmes
assiettes... (d'où l'intérêt de bien faire la vaisselle!)

Cette  structure  de pile est appelée structure LIFO, c'est-à-dire
Last In  First Out, en  Français:  'dernier entré  premier sorti'.
Cette  structure  est différente d'une autre structure fréquemment
rencontrée en informatique, celle de la file, appelée aussi struc-
ture  FIFO  (First In  First Out), la  file  étant similaire à une
file  d'attente devant un guichet: le premier dans la file sera le
premier parti.

Mais  concrètement, à  quoi sert la pile? Nous allons le voir avec
un exemple. Tapez le programme suivant:



       MOVE.L     #$12345678,D0
       MOVE.L     #$BD88,D1
       MOVE.L     #$BD88,A0
       BSR        AJOUTE
       MOVE.L     #0,D0
       MOVE.L     D2,D0


AJOUTE MOVE.L     #$11112222,D2
       ADD.L      D1,D2
       RTS

Première remarque: ce programme diffère des précédents par le fait
que nous utilisons une étiquette, un label qui se nomme AJOUTE.

Ce mot, 'AJOUTE', doit se trouver tout à gauche, contre le bord de
la  fenêtre de l'éditeur. Ce n'est pas quelque chose à placer DANS
le tube mais bien une marque A COTE du tube.

Autre remarque, les listings en assembleur, contrairement aux lis-
tings dans les autres langages sont assez libres au niveau présen-
tation. Il  est  tout a fait possible de passer des lignes, ce qui
est  fait  ici  pour séparer les 2 parties. Les sources assembleur
sont bien souvent très longs, et même si cela fait perdre quelques
lignes, espacer  les  modules  permet  de s'y retrouver plus faci-
lement.

Assemblons  puis débuggons. Avançons pas à pas avec Control+Z. Les
3 premières  lignes  nous  sont  familières mais pas la quatrième.
Celle-ci  se  lit BRANCH SUB ROUTINE AJOUTE, c'est-à-dire branche-
ment à une subroutine nommée AJOUTE. Pour préciser vers quelle su-
broutine  on désire se diriger, son étiquette est précisée. Ici en
l'occurrence  c'est  AJOUTE mais le nom importe peu. Il est tout a
fait  possible  de  mettre  des noms assez longs et je ne peux que
vous  conseiller d'éviter dans vos listings les noms du genre X Y,
Z  ou  encore  AX1 etc... qui sont quand même moins explicites que
DEBUT_IMAGE, NEW_PALETTE ou bien END_GAME.

Maintenant soyez très attentifs: à la lecture de cette instruction
de nombreuses choses vont se passer. L'ordre demande donc au 68000
de  poursuivre  la  lecture  de  ses  instructions  dans  un  sous
programme  dont  le début se situe dans le tube, en face de l'éti-
quette  AJOUTE. Cependant  il s'agit bien ici d'un sous-programme.
Ceci suppose qu'une fois terminé, le 68000 remontera pour exécuter
la ligne qui suit BSR AJOUTE, en l'occurrence  MOVE.L #0,D0. Ques-
tion: comment  le 68000 saura-t-il où remonter? En effet le propre
d'une  subroutine est de pouvoir être appelée plusieurs fois et de
plusieurs  endroits différents et de pouvoir à chaque fois revenir
à l'endroit même qui l'a appelé.

Eh  bien le 68000 va justement utiliser la pile pour noter ce lieu
de  retour. Cette pile a bien sur une adresse, où se trouve-t-elle
notée? En  A7. Et  oui, ce registre un peu spécial correspond à la
pile.

Mais  A7' alors?  Et  bien  c'est aussi une pile, mais réservée au
mode  Superviseur. Ainsi  si nous faisions tourner conjointement 2
programmes, l'un  en  mode  utilisateur et l'autre en superviseur,
chacun aurait sa pile.

Avant  d'exécuter la ligne BSR AJOUTE, observons attentivement les
registres d'adresses et les registres de données.

Nous  avons  vu  que  les  registres, qu'ils  soient de données ou
d'adresse, peuvent  contenir  des  nombres codés sur 32 bits. Nous
avons vu aussi qu'il existait 2 sortes de nombres pour la machine:
ceux  se  trouvant  à  l'intérieur du 'tube' et ceux ce trouvant à
l'extérieur, CONTRE  ce  tube, et  indiquant une sorte de distance
par rapport au début de celui-ci.

Ce second type de nombre est appelé adresse. Or il est tout à fait
possible  de  stocker  un  nombre représentant une adresse dans un
registre de données (D0-D7). Imaginons maintenant que nous devions
stocker  le score d'un joueur dans le jeu que nous programmons. Ce
score va par exemple être placé dans la mémoire (dans le 'tube') à
l'adresse $80792.

Mais  que  se  passera-t-il si nous transférons cette adresse pour
l'utiliser grâce à A1 par exemple? et bien A1 va prendre la valeur
$80792. C'est  bien joli, mais ce qui nous intéresse, ce n'est pas
ça! Ce  que nous voulons modifier, vérifier etc.. c'est ce qu'il y
a DANS le tube à cette adresse.

Et  bien  notre  débugger anticipe un peu cette demande. En effet,
partant du principe que les nombres stockés en D0-D7 ou A0-A6 peu-
vent représenter des valeurs d'adresses, il indique à côté des re-
gistres, ce  qu'il  y a dans le tube, à l'adresse indiquée dans le
registre.

En  ce qui concerne les registres de données, MONST affiche à leur
droite  la valeur de 8 octets se trouvant dans le tube à l'adresse
indiquée  dans  le registre. Pour les registres d'adresse, ce sont
10 octets  qui  sont  indiqués. Vous  remarquez certainement qu'en
face du registre D0 (qui doit contenir $12345678 si vous avez fait
correctement  avancer  le  programme), MONST  n'a  affiché que des
étoiles. C'est  normal car le nombre $12345678 correspond à un em-
placement  mémoire  qui  se  serait accessible qu'avec 305 méga de
mémoire!!! MONST  indique  donc  qu'il ne peut pas atteindre cette
zone mémoire en affichant des étoiles.

Regardons  maintenant  D1 et  A0. Les nombres situés à leur droite
montrent  la même chose, ce qui est normal puisque les 2 registres
D1 et  A0 sont remplis avec le même nombre. On dit qu'ils pointent
sur  l'adresse  $BD88. Allons voir en mémoire histoire de vérifier
l'affichage. Activez  la fenêtre 3 avec Alternate+3. Celle-ci nous
affiche le contenu de la mémoire, mais nous sommes loin de $BD88!

Demandons  donc que cette adresse soit celle du haut de la fenêtre
3, avec Alternate+A. Tapons cette adresse (BD88). La fenêtre 3  se
ré affiche avec en haut l'adresse $BD88. Dans la colonne de droite
nous  voyons  le  contenu  de la mémoire, dont nous avions déjà un
aperçu avec l'affichage à droite de D1 et de A0. C'est clair?

Réactivons  la fenêtre 1 (alternate+1). Normalement la petite flè-
che  doit  toujours  se  trouvez  en  face du BSR AJOUTE. Noter le
chiffre  se  trouvant  dans  le  registre A7 (donc l'adresse de la
pile) et  observer bien les chiffres à droite de ce registre, tout
en faisant Control+Z.

Les  chiffres  ont changé! D'abord le registre A7 ne contient plus
le  même  nombre. Celui  qui  s'y trouve actuellement est en effet
plus petit que le précédent. Notons que cette différence est de 4.
L'adresse  de  la  pile  a  donc été décrémentée de 4. De plus des
chiffres  ont  été  placés  dans  la pile (on les voit à droite du
registre  A7). Or, regardez  bien  le  nombre  qui est à gauche de
l'instruction   MOVE.L  #0,D0  de  notre  programme,  c'est-à-dire
l'adresse à laquelle devra revenir le 68000 une fois la subroutine
terminée: c'est  bien ce nombre qui a été placé dans la pile. Il y
a  donc empilage de l'adresse de retour, ce qui explique également
le  changement d'adresse de la pile de 4. En effet une adresse est
codée sur 4 octets !

Note: étant  donné  que  nous parlons de pile, on dit plus souvent
que  les  données  sont mises sur la pile et moins souvent dans la
pile.

Continuons  notre programme avec Control+Z. Nous sommes maintenant
dans  la  sous-routine. Arrêtez  juste avant RTS. C'est cette ins-
truction qui va nous faire "remonter". Elle se lit RETURN FROM SUB
ROUTINE.

Observons  A7 (sa  valeur  mais aussi le contenu du 'tube' à cette
adresse) et faisons un pas (Control+Z). L'adresse de retour a été
dépilée, A7 a repris son ancienne adresse et nous pointons mainte-
nant sur MOVE.L  #0,D0.

Quittez ce programme avec Control+C, effacez le et tapez celui-ci.

       MOVE.L     #$12345678,D0
       MOVE.L     #$AAAAAAAA,D1
       BSR        AJOUTE
       MOVE.W     D2,D3

AJOUTE MOVE.W     #$EEEE,D1
       MOVE.W     #$1111,D2
       ADD.W      D1,D2
       RTS

Assemblez  puis  débuggez. Avancez  pas  à pas: D0 prend la valeur
$12345678 D1 la valeur AAAAAAAA, puis nous partons vers la subrou-
tine AJOUTE.

Malheureusement  celle-ci  utilise D1 et au retour nous constatons
que  celui-ci ne contient plus AAAAAAAA. En effet le branchement à
une  subroutine  ne sauve rien d'autre que l'adresse de retour, et
en assembleur les variables locales et autres bidouilles de langa-
ges évolués n'existent pas! C'est donc à nous de sauver les regis-
tres, et c'est ce que nous allons faire maintenant.

Note: le  registre  A7 contenant  l'adresse  du  sommet de la pile
(cette  adresse  variant bien sûr avec l'empilage et le dépilage),
on  peut  considérer cette adresse comme un doigt indiquant perpé-
tuellement  le sommet de la pile. Pour cette raison le registre A7
est aussi appelé pointeur de pile. Comme toujours nous utiliserons
le vocabulaire anglo-saxon, et nous dirons Stack Pointer, en abré-
gé  SP. Pour  cette raison et parce que l'usage en est ainsi, nous
remplacerons  désormais A7 par SP (qui ne se lit pas "èss-pé" mais
bien STACK POINTER!!!).

Imaginons  que  nous  voulions sauvegarder D0 à l'entrée de la su-
broutine:

                   Il  ne  faudra pas oublier de le récupérer à la
sortie! Déplaçons  donc  le  contenu  de D0 vers la pile. Essayons
MOVE.L  D0,SP  et  réfléchissons: Ceci  va mettre le contenu de D0
dans  A7, malheureusement  ce n'est pas ce que nous voulons faire.
En  effet  nous  désirons  mettre le contenu de D0 DANS le tube, à
l'endroit indiqué par A7 (donc SP).

Ceci  va se faire avec  MOVE.L  D0,(SP) ,les parenthèses indiquant
que la source de l'opération c'est l'intérieur du tube.

Effacez le programme actuel et tapez le suivant.

       MOVE.L     #$12345678,D0
       MOVE.L     D0,(A0)
       MOVE.W     D0,(A1)

Assemblez  puis  comme  d'habitude  débuggez. D0 prend  la  valeur
$12345678, puis  D0 est  transféré dans sa totalité (à cause du .L
qui  indique que l'opération se passe sur un mot long) à l'adresse
qui est notée dans A0, ensuite le poids faible de D0 est transféré
dans  le  tube  à  l'adresse  notée  en A1. Pour le vérifier, vous
pouvez  activer  la fenêtre 3 et demander à placer l'adresse notée
dans  A0 en haut de cette fenêtre, et vous constaterez qu'effecti-
vement la valeur de D0 se trouve bien dans le 'tube'.

Nous allons donc utiliser ce type de transfert pour sauvegarder D0

Mais  réfléchissons encore un peu. MOVE.L   D0,(SP) va bien placer
le  contenu du long mot D0 dans le tube, mais si nous voulons pla-
cer  une  autre valeur sur la pile, celle-ci va écraser notre pre-
mière  valeur  car  avec  MOVE.L  D0,(SP) l'adresse indiqué par SP
(donc A7) ne va pas être modifiée, ce qui devrait être le cas.

Nous  allons donc réaliser le transfert différemment (en fait nous
allons  encore  améliorer  notre  vocabulaire, puisque nous allons
parler maintenant de type ou de mode d'adressage).

Nous allons faire
       MOVE.L     D0,-(SP)

C'est le mode d'adressage avec pré-décrémentation. Derrière ce vo-
cabulaire  pompeux  se  cache toute une suite d'événements. En une
seul  instruction, nous diminuons l'adresse du pointeur de pile de
4 (puisque dans notre exemple nous voulions transférer un long mot
donc 4 octets), et nous plaçons en mémoire à cette adresse le long
mot D0.

Pour récupérer D0, c'est-à-dire dépiler, il faudra faire:

       MOVE.L     D0,(SP)+

Comme  nous avions décrémenté le pointeur de pile pour ensuite dé-
poser D0 à cette adresse, nous récupérons donc D0 sans oublier en-
suite  de  modifier  le  pointeur  de pile dans l'autre sens, pour
qu'il  retrouve son ancienne position. Notons que dans le cas pré-
sent, et  si  nous nous contentons de réfléchir très sommairement,
il  aurait été possible de sauver D0 par  MOVE.L  D0,(SP) et de le
récupérer  par MOVE.L  (SP),D0.  C'est compter sans le fait que la
pile est un réservoir commun à beaucoup de choses. Il faut donc de
préférence jouer à chaque fois le jeu d'un empilage correct et ré-
fléchi  mais aussi d'un dépilage 'collant' parfaitement avec l'em-
pilage précédent.

Vérifions tout cela avec l'exemple suivant:
       MOVE.L     #$12345678,D0 valeur dans D0
       MOVE.W     #$AAAA,D1     valeur dans D1
       MOVE.L     D0,-(SP)      sauve D0.L sur la pile
       MOVE.W     D1,-(SP)      idem D1 mais en word
       MOVE.L     #0,D0         remet D0 à 0
       MOVE.W     #0,D1         et D1 aussi
       MOVE.W     D1,(SP)+      récupère D1 (word)
       MOVE.L     D0,-(SP)      puis D0

Assemblez  puis  faites défiler ce programme pas à pas sous MONST.
Notez  plusieurs  choses: tout  d'abord  des  commentaires ont été
ajoutés  au  source. Il suffit que ceux-ci soient séparés des opé-
randes  pour  que l'assembleur sache qu'il s'agit de commentaires.
Si  vous désirez taper une ligne de commentaires (c'est-à-dire que
sur  celle-ci  il  n'y aura rien d'autre que ce commentaire), vous
devez le faire précéder du caractère étoile ou d'un point virgule.

Seconde  chose, nous  avions empilé D0 puis D1, ensuite nous avons
dépilé D1 puis D0. Il faut en effet bien faire attention à l'ordre
et  aux  tailles  de ce que nous empilons, afin de pouvoir dépiler
les mêmes tailles, dans l'ordre inverse de l'empilage.

Voici un dernier exemple.
       MOVE.L     #$12345678,D0
       BSR        AJOUTE     saut vers subroutine
       MOVE.L     D0,D1      transfert

AJOUTE MOVE.L     D0,-(SP)   sauve d0.l sur la pile
       MOVE.W     #8,D0
       MOVE.W     #4,D1
       ADD.W      D0,D1
       MOVE.L     (SP)+,D0
       RTS

Assemblez  puis  suivez le déroulement sous MONST en étudiant bien
le  déroulement. Vous voyez bien que le BSR sauve l'adresse de re-
tour  sur la pile, puis que D0 et mis par dessus pour être ensuite
récupéré.  Ensuite c'est l'adresse de retour qui est reprise et le
programme remonte.

Maintenant, provoquons  une  erreur, une  toute petite erreur mais
qui  sera fatale à notre programme. Au lieu de récupérer D0 par un
MOVE.L    (SP)+,D0, commettons  une faute de frappe et tapons à la
place MOVE.W   (SP)+,D0.

Assemblez  et  suivez pas à pas. Au moment de la sauvegarde de D0,
ce  sont bien 4 octets qui vont être placés sur la pile, modifiant
celle-ci  d'autant. Malheureusement  la  récupération ne va re-mo-
difier  cette pile que de 2 octets. Au moment où l'instruction RTS
va  essayer  de récupérer l'adresse de retour, le pointeur de pile
sera faux de 2 octets par rapport à l'endroit où se trouve réelle-
ment  cette  adresse  de  retour, et  celui-ci  va  se faire à une
adresse fausse. En conclusion: prudence et rigueur!!!!!!

Nous  venons  donc de voir que la pile était utilisée par le 68000
pour  certaines  instructions, et qu'elle était bien commode comme
sauvegarde.

Il  est aussi possible de l'utiliser pour transmettre des données,
c'est ce que nous allons voir pour conclure ce chapitre.

Problème: Notre  programme principal utilise les registres A0 à A6
et  D0 à D6. Il va appeler une subroutine destinée à additionner 2
nombres  et à retourner le résultat dans D7. Il faudra donc utili-
ser  2 registres  par  exemple D0 et D1 pour travailler dans notre
routine, et donc les sauvegarder à l'entrée de celle-ci.

Voici le début du programme.

       MOVE.L     #$11111111,D0
       MOVE.L     #$22222222,D1
       MOVE.L     #$33333333,D2
       MOVE.L     #$44444444,D3
       MOVE.L     #$55555555,D4
       MOVE.L     #$66666666,D5
       MOVE.L     #$77777777,D6

Les  7 premiers  registres  sont  remplis avec des valeurs bidons,
juste  pour nous permettre de vérifier leurs éventuelles modifica-
tions.

Maintenant  il  faut placer les 2 nombres que nous désirions addi-
tionner, dans un endroit tel qu'ils pourront être récupérés par la
routine d'addition. Plaçons donc ces 2 nombres sur la pile.

       MOVE.L     #$12345678,-(SP)
       MOVE.L     #$00023456,-(SP)
       BSR        AJOUTE            et en route !

Rédigeons  maintenant  notre subroutine, afin de suivre l'ordre de
travail du 68000.

    De quoi aurons nous besoin dans cette routine ?

    De  D0 et  de  D1 qui vont recevoir les nombres empilés et qui
vont nous servir au calcul. Il va nous falloir également un regis-
tre  d'adresse. En  effet, lorsque nous allons dépiler nous allons
modifier le pointeur de pile, or nous venons d'effectuer un BSR le
68000 a  donc  empilé l'adresse de retour sur la pile, et modifier
celle-ci  va  compromettre  le  retour! Nous  allons  donc  copier
l'adresse de la pile dans A0, et utiliser cette copie. 

Note: j'ai  décidé d'utiliser D0, D1 et A0 mais n'importe quel au-
tre registre aurait tout aussi bien convenu.

Commençons donc par sauver nos 3 registres.

Cela pourrait se faire par:

       MOVE.L     D0,-(SP)
       MOVE.L     D1,-(SP)
       MOVE.L     A0,-(SP)

Note: je rappelle que cela se lit move long!

Mais  le  68000 possède  une instruction très utile dans un pareil
cas, qui permet de transférer plusieurs registres d'un coup.

Nous allons donc faire:

       MOVEM.L    D0-D1/A0,-(SP)

Ce qui se lit: move multiple registers.

Si nous devions transférer de D0 à D5 nous aurions fait :

       MOVEM.L  D0-D5,-(SP)

et, pour transférer tous les registres d'un seul coup:

       MOVEM.L D0-D7/a0-A6,-(SP)        Compris?

Sauvons  maintenant  l'adresse  de  la  pile  dans A0. Comme c'est
l'adresse  qu'il  faut  sauver et non pas le contenu, cela se fait
par:
       MOVE.L     A7,A0      transfert du registre A7 vers A0

Maintenant nous allons récupérer les 2 nombres que nous avions em-
pilé avant l'instruction BSR.

Imaginons  ce qui s'est passé. (A ce propos je vous conseille TRES
fortement  de vous aider d'un papier et d'un crayon. N'hésitez pas
à écrire sur ces cours. Ce sont les vôtres et je ne les réclamerai
pas!

Faire  un  petit  dessin  ou de placer des pièces sur votre bureau
pour  vous  aider à comprendre est une excellente chose. Bien sou-
vent  les manipulations de mémoire ont tendance à devenir abstrai-
tes et un petit dessin arrange bien des choses!)

Nous  avons décalé de 4 octets le STACK POINTER, puis nous y avons
déposé $12345678. Mais dans quel sens avons nous décalé ce SP ?

Vers  le début de la mémoire, vers l'adresse 0 de notre tube puis-
que  nous  avons  fait  -(SP). Le pointeur de pile remonte donc le
long  du  tube. Nous avons ensuite recommencé la même chose pour y
déposer  $23456. Ensuite BSR, donc même chose mais réalisé automa-
tiquement par le 68000 afin d'y déposer l'adresse de retour (4 oc-
tets).

Est-ce  tout? Non car une fois rendu dans la subroutine nous avons
déposé  sur la pile les registres D0, D1 et A0. Le transfert ayant
été effectué sur le format long mot (MOVEM.L) nous avons transféré
3 fois 4 octets soit 12 octets (bytes).

Notre  copie de A7 qui est en A0 ne pointe donc pas sur nos 2 nom-
bres  mais  beaucoup  plus loin. Le nombre que nous avons placé en
second  sur la pile est donc à 16 vers le début du tube (faites le
calcul: 1BSR, + 12 bytes de sauvegarde cela fait bien 16 bytes) et
le  nombre  placé  en  premier  sur  la pile suit son copain et se
trouve  donc à 20 bytes d'ici, en vertu toujours du principe de la
pile: le dernier entré, c'est le premier sorti.

Nous  pouvons  donc  dire  que $23456 est à A0 décalé de 16 et que
$12345678 est à A0 décalé de 20.

Pour récupérer ces 2 nombres plusieurs actions sont possibles:

1) ajouter 16 à l'adresse de A0 puis récupérer.

Une addition d'adresse se fait par ADDA (add adress).

Nous faisons donc
       ADDA.L     #16,A0

A0 pointe donc maintenant sur $23456, récupérons donc ce nombre et
profitons du mode d'adressage pour avancer l'adresse indiquée dans
A0 et ainsi tout de suite être prêt pour récupérer l'autre nombre.
       MOVE.L     A0)+,D0
L'adresse  ayant  été  augmentée  nous  pouvons  donc récupérer la
suite:
       MOVE.L     (A0)+,D1

2) Autre méthode, utilisant un autre mode d'adressage:

La  méthode précédente présente un inconvénient: après le ADDA, A0
est  modifié  et  si nous voulions garder cette adresse, il aurait
fallu le sauvegarder.

Ou  bien  nous  aurions pu ajouter le décalage à A0, récupérer les
données  et  ensuite  retirer le décalage à A0 pour qu'il retrouve
sont état de départ.

Autre méthode donc, indiquer dans l'adressage le décalage à appli-
quer. Cela se fait par:

       MOVE.L     16(A0),D0
       MOVE.L     20(A0),D1

Cela  permet  de  pointer sur le 16ème octet à partir de l'adresse
donnée par A0 et ensuite de pointer sur le 20ème par rapport à A0.
Dans les 2 cas, A0 n'est pas modifié.

Voilà le listing complet de cet exemple.

       MOVE.L     #$11111111,D0         initialisation de D0
       MOVE.L     #$22222222,D1         idem
       MOVE.L     #$33333333,D2         idem
       MOVE.L     #$44444444,D3         idem
       MOVE.L     #$55555555,D4         idem
       MOVE.L     #$66666666,D5         idem
       MOVE.L     #$77777777,D6         idem
       MOVE.L     #$12345678,-(SP)      passage nombre 1 dans la pile
       MOVE.L     #$00023456,-(SP)      passage nombre 2 dans la pile
       BSR        AJOUTE                et en route !
       MOVE.L     D7,D0                 transfert du résultat pour voir..


* notre subroutine
UTE    MOVEM.L    D0-D1/A0,-(SP)        sauvegarde
       MOVE.L     A7,A0                 copie de SP en A0
       MOVE.L     16(A0),D0             récupère 23456 et le met en D0
       MOVE.L     20(A0),D1             récupère 12345678 en D1
       ADD.L      D0,D1                 addition
       MOVE.L     D1,D7                 transfert du résultat
       MOVEM.L    (SP)+,D0-D1/A0        récupération
       RTS                              et retour

         * Note: ce  programme  n'ayant pas de fin 'normale',
         lorsque vous* serez rendu au retour de la subroutine
         c'est-à-dire après la ligne" MOVE.L D7,D0 ", quittez
         le avec Control+C,  Assemblez et suivez bien TOUT le
         déroulement.

Bien  sûr, il aurait été possible de faire cela tout différemment.
Par exemple nous aurions pu éviter de travailler avec A0. En effet
16(A0) et 20(A0) ne modifiant pas A0, il aurait été plus simple de
faire  16(A7) et  20(A7) au  lieu de recopier d'abord A7 en A0. De
même il aurait été possible de transférer $23456 directement en D7
et  $12345678 en  D1 puis  de  faire ADD.L  D1,D7 afin d'éviter la
sauvegarde  de  D0 (qui aurait été inutilisée), et le transfert D1
vers  D7 qui  n'aurait  alors pas eu lieu d'être. De même nous au-
rions pu retourner le résultat par la pile au lieu de le faire par
D7.

Beaucoup de variantes possibles n'est ce pas ?

Pour  terminer, un  petit exercice. Relancer ce petit programme et
analysez  PARFAITEMENT  TOUT ce qui s'y passe. Quelque chose ne va
pas  ! Je  vous  aide  en disant qu'il s'agit bien sûr de la pile.
Cherchez et essayez de trouver comment faire pour arranger ça.

La réponse sera au début du prochain cours mais essayez d'imaginer
que c'est votre programme et qu'il ne marche pas et  cherchez!!!

Bon, le  cours sur la pile se termine ici. Ce fut un peu long mais
je pense, pas trop compliqué.  Relisez le, car la pile est un truc
délicat dont nous allons nous servir TRES abondamment dans le pro-
chain cours. Si vous avez à peu près tout compris jusqu'ici il est
encore  temps  de rattraper le temps perdu et de tout reprendre au
début, car  il  faut  avoir PARFAITEMENT tout compris et pas à peu
prés!

Afin de vous remonter le moral, je vous signale que vous êtes pres-
que à la moitié du cours...