COURS 6.TXT/fr: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
Olivier.jan (talk | contribs) m (Olivier.jan moved page COURS 6.TXT to COURS 6.TXT/fr: Renaming for language version) |
||
(12 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{Languages|COURS 6.TXT}} |
||
<pre> |
<pre> |
||
****************************************************************** |
****************************************************************** |
||
Line 4: | Line 5: | ||
* COURS D'ASSEMBLEUR 68000 SUR ATARI ST * |
* COURS D'ASSEMBLEUR 68000 SUR ATARI ST * |
||
* * |
* * |
||
− | * par Le |
+ | * par Le Féroce Lapin (from 44E) * |
* * |
* * |
||
− | * Cours |
+ | * Cours numéro 6 * |
* * |
* * |
||
****************************************************************** |
****************************************************************** |
||
− | LA PILE Nous avons |
+ | LA PILE Nous avons déjà utilisé la notion de 'tube' en ce qui |
− | concerne la |
+ | concerne la mémoire. Nous pouvons y stocker différentes choses, et |
− | si nous nous rappelons l'adresse, nous pouvons revenir plus tard |
+ | si nous nous rappelons l'adresse, nous pouvons revenir plus tard à |
− | cet endroit pour y |
+ | cet endroit pour y récupérer ce que nous y avions déposé. |
Essayez avec ce petit programme: |
Essayez avec ce petit programme: |
||
Line 22: | Line 23: | ||
MOVE.L $493E0,D0 |
MOVE.L $493E0,D0 |
||
− | Assemblez puis passez sous MONST. Avancez en pas |
+ | Assemblez puis passez sous MONST. Avancez en pas à pas. D0 est |
− | d'abord rempli avec $12345678, puis le contenu de 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 |
+ | 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) |
de celle-ci sur l'adresse $493E0 ([Alternate+A] puis tapez 493E0) |
||
− | Vous voyez bien 12345678 |
+ | Vous voyez bien 12345678 à cet endroit dans le 'tube'. Si j'ai |
− | choisit cette adresse c'est parce qu'elle se situe |
+ | 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 |
+ | elle est suffisamment éloignée pour ne pas se trouver dans GENST |
− | ou MONST. En effet il n'y a qu'un 'tube' |
+ | ou MONST. En effet il n'y a qu'un 'tube' mémoire! Nous sommes donc |
− | en train d' |
+ | en train d'écrire dans la mémoire alors qu'une partie de celle-ci |
− | est |
+ | 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! |
certainement quelques plantages de ceux-ci! |
||
− | Continuons en pas |
+ | Continuons en pas à pas, nous mettons D0 à 0 puis le contenu de |
l'adresse $493E0 (sans #) est remis dans D0. |
l'adresse $493E0 (sans #) est remis dans D0. |
||
− | La pile, c'est une partie de ce tube, mais que nous allons |
+ | La pile, c'est une partie de ce tube, mais que nous allons gérer |
− | d'une |
+ | 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 |
+ | 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 |
+ | c'est le gain de temps (pas la peine de se demander à quelle |
− | adresse on a |
+ | adresse on a stocké les données) et un gain de place (si c'est |
− | pour stocker temporairement des |
+ | pour stocker temporairement des données, inutile de conserver une |
− | portion de 'tube' juste pour |
+ | portion de 'tube' juste pour ça). |
− | Par contre l' |
+ | Par contre l'inconvénient c'est que la gestion doit être rigou- |
reuse. Imaginons que j'empile un premier chiffre puis 10 autres |
reuse. Imaginons que j'empile un premier chiffre puis 10 autres |
||
− | par dessus. Ensuite je |
+ | 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 |
+ | croyant retrouver le premier chiffre empilé, je récupérerai en |
− | fait le premier de la |
+ | fait le premier de la série de 10. |
Nous en concluons 2 choses: d'abord que la pile est un moyen sim- |
Nous en concluons 2 choses: d'abord que la pile est un moyen sim- |
||
− | ple pour sauvegarder des |
+ | ple pour sauvegarder des données, mais ensuite que c'est une |
− | source de |
+ | source de désagrément potentiel, tel que certains programmeurs hé- |
− | site |
+ | site à s'en servir. C'est généralement à cause d'un manque de ri- |
− | gueur ce qui, je l' |
+ | gueur ce qui, je l'espère ne vous arrivera pas. |
− | Une autre remarque: le dernier |
+ | Une autre remarque: le dernier élément placé sur la pile sera tou- |
− | jours le premier |
+ | 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 |
+ | lui d'une pile d'assiettes: Regardez chez vous, il y a sûrement |
− | une |
+ | une énorme pile d'assiettes, mais par le simple fait que le range- |
− | ment |
+ | ment après le lavage se fait par empilage et que mettre la table |
− | se fait par |
+ | se fait par dépilage, vous mangez en fait toujours dans les mêmes |
− | assiettes... (d' |
+ | assiettes... (d'où l'intérêt de bien faire la vaisselle!) |
− | Cette structure de pile est |
+ | Cette structure de pile est appelée structure LIFO, c'est-à-dire |
− | Last In First Out, en |
+ | Last In First Out, en Français: 'dernier entré premier sorti'. |
− | Cette structure est |
+ | 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 |
+ | ture FIFO (First In First Out), la file étant similaire à une |
file d'attente devant un guichet: le premier dans la file sera le |
file d'attente devant un guichet: le premier dans la file sera le |
||
premier parti. |
premier parti. |
||
− | Mais |
+ | Mais concrètement, à quoi sert la pile? Nous allons le voir avec |
un exemple. Tapez le programme suivant: |
un exemple. Tapez le programme suivant: |
||
Line 96: | Line 97: | ||
RTS |
RTS |
||
− | + | Première remarque: ce programme diffère des précédents par le fait |
|
− | que nous utilisons une |
+ | que nous utilisons une étiquette, un label qui se nomme AJOUTE. |
− | Ce mot, 'AJOUTE', doit se trouver tout |
+ | Ce mot, 'AJOUTE', doit se trouver tout à gauche, contre le bord de |
− | la |
+ | la fenêtre de l'éditeur. Ce n'est pas quelque chose à placer DANS |
le tube mais bien une marque A COTE du tube. |
le tube mais bien une marque A COTE du tube. |
||
Autre remarque, les listings en assembleur, contrairement aux lis- |
Autre remarque, les listings en assembleur, contrairement aux lis- |
||
− | tings dans les autres langages sont assez libres au niveau |
+ | 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 |
tation. Il est tout a fait possible de passer des lignes, ce qui |
||
− | est fait ici pour |
+ | est fait ici pour séparer les 2 parties. Les sources assembleur |
− | sont bien souvent |
+ | 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- |
lignes, espacer les modules permet de s'y retrouver plus faci- |
||
lement. |
lement. |
||
− | Assemblons puis |
+ | Assemblons puis débuggons. Avançons pas à pas avec Control+Z. Les |
− | 3 |
+ | 3 premières lignes nous sont familières mais pas la quatrième. |
− | Celle-ci se lit BRANCH SUB ROUTINE AJOUTE, c'est- |
+ | Celle-ci se lit BRANCH SUB ROUTINE AJOUTE, c'est-à-dire branche- |
− | ment |
+ | ment à une subroutine nommée AJOUTE. Pour préciser vers quelle su- |
− | broutine on |
+ | 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 |
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 |
fait possible de mettre des noms assez longs et je ne peux que |
||
− | vous conseiller d' |
+ | vous conseiller d'éviter dans vos listings les noms du genre X Y, |
− | Z ou encore AX1 etc... qui sont quand |
+ | Z ou encore AX1 etc... qui sont quand même moins explicites que |
DEBUT_IMAGE, NEW_PALETTE ou bien END_GAME. |
DEBUT_IMAGE, NEW_PALETTE ou bien END_GAME. |
||
− | Maintenant soyez |
+ | Maintenant soyez très attentifs: à la lecture de cette instruction |
de nombreuses choses vont se passer. L'ordre demande donc au 68000 |
de nombreuses choses vont se passer. L'ordre demande donc au 68000 |
||
de poursuivre la lecture de ses instructions dans un sous |
de poursuivre la lecture de ses instructions dans un sous |
||
− | programme dont le |
+ | 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. |
quette AJOUTE. Cependant il s'agit bien ici d'un sous-programme. |
||
− | Ceci suppose qu'une fois |
+ | 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- |
la ligne qui suit BSR AJOUTE, en l'occurrence MOVE.L #0,D0. Ques- |
||
− | tion: comment le 68000 saura-t-il |
+ | tion: comment le 68000 saura-t-il où remonter? En effet le propre |
− | d'une subroutine est de pouvoir |
+ | d'une subroutine est de pouvoir être appelée plusieurs fois et de |
− | plusieurs endroits |
+ | 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 |
Eh bien le 68000 va justement utiliser la pile pour noter ce lieu |
||
− | de retour. Cette pile a bien sur une adresse, |
+ | 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. |
pile. |
||
− | Mais A7' alors? Et bien c'est aussi une pile, mais |
+ | Mais A7' alors? Et bien c'est aussi une pile, mais réservée au |
mode Superviseur. Ainsi si nous faisions tourner conjointement 2 |
mode Superviseur. Ainsi si nous faisions tourner conjointement 2 |
||
programmes, l'un en mode utilisateur et l'autre en superviseur, |
programmes, l'un en mode utilisateur et l'autre en superviseur, |
||
chacun aurait sa pile. |
chacun aurait sa pile. |
||
− | Avant d' |
+ | Avant d'exécuter la ligne BSR AJOUTE, observons attentivement les |
− | registres d'adresses et les registres de |
+ | registres d'adresses et les registres de données. |
− | Nous avons vu que les registres, qu'ils soient de |
+ | Nous avons vu que les registres, qu'ils soient de données ou |
− | d'adresse, peuvent contenir des nombres |
+ | 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: |
avons vu aussi qu'il existait 2 sortes de nombres pour la machine: |
||
− | ceux se trouvant |
+ | ceux se trouvant à l'intérieur du 'tube' et ceux ce trouvant à |
− | l' |
+ | l'extérieur, CONTRE ce tube, et indiquant une sorte de distance |
− | par rapport au |
+ | par rapport au début de celui-ci. |
− | Ce second type de nombre est |
+ | Ce second type de nombre est appelé adresse. Or il est tout à fait |
− | possible de stocker un nombre |
+ | possible de stocker un nombre représentant une adresse dans un |
− | registre de |
+ | registre de données (D0-D7). Imaginons maintenant que nous devions |
stocker le score d'un joueur dans le jeu que nous programmons. Ce |
stocker le score d'un joueur dans le jeu que nous programmons. Ce |
||
− | score va par exemple |
+ | score va par exemple être placé dans la mémoire (dans le 'tube') à |
l'adresse $80792. |
l'adresse $80792. |
||
− | Mais que se passera-t-il si nous |
+ | Mais que se passera-t-il si nous transférons cette adresse pour |
− | l'utiliser |
+ | l'utiliser grâce à A1 par exemple? et bien A1 va prendre la valeur |
− | $80792. C'est bien joli, mais ce qui nous |
+ | $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 |
+ | a DANS le tube à cette adresse. |
− | Et bien notre |
+ | Et bien notre débugger anticipe un peu cette demande. En effet, |
− | partant du principe que les nombres |
+ | partant du principe que les nombres stockés en D0-D7 ou A0-A6 peu- |
− | vent |
+ | vent représenter des valeurs d'adresses, il indique à côté des re- |
− | gistres, ce qu'il y a dans le tube, |
+ | gistres, ce qu'il y a dans le tube, à l'adresse indiquée dans le |
registre. |
registre. |
||
− | En ce qui concerne les registres de |
+ | En ce qui concerne les registres de données, MONST affiche à leur |
− | droite la valeur de 8 octets se trouvant dans le tube |
+ | 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 |
+ | 10 octets qui sont indiqués. Vous remarquez certainement qu'en |
face du registre D0 (qui doit contenir $12345678 si vous avez fait |
face du registre D0 (qui doit contenir $12345678 si vous avez fait |
||
− | correctement avancer le programme), MONST n'a |
+ | correctement avancer le programme), MONST n'a affiché que des |
− | + | étoiles. C'est normal car le nombre $12345678 correspond à un em- |
|
− | placement |
+ | 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 |
+ | zone mémoire en affichant des étoiles. |
− | Regardons maintenant D1 et A0. Les nombres |
+ | Regardons maintenant D1 et A0. Les nombres situés à leur droite |
− | montrent la |
+ | montrent la même chose, ce qui est normal puisque les 2 registres |
− | D1 et A0 sont remplis avec le |
+ | D1 et A0 sont remplis avec le même nombre. On dit qu'ils pointent |
− | sur l'adresse $BD88. Allons voir en |
+ | sur l'adresse $BD88. Allons voir en mémoire histoire de vérifier |
− | l'affichage. Activez la |
+ | l'affichage. Activez la fenêtre 3 avec Alternate+3. Celle-ci nous |
− | affiche le contenu de la |
+ | affiche le contenu de la mémoire, mais nous sommes loin de $BD88! |
− | Demandons donc que cette adresse soit celle du haut de la |
+ | Demandons donc que cette adresse soit celle du haut de la fenêtre |
− | 3, avec Alternate+A. Tapons cette adresse (BD88). La |
+ | 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 |
+ | 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 |
che doit toujours se trouvez en face du BSR AJOUTE. Noter le |
||
chiffre se trouvant dans le registre A7 (donc l'adresse de la |
chiffre se trouvant dans le registre A7 (donc l'adresse de la |
||
− | pile) et observer bien les chiffres |
+ | pile) et observer bien les chiffres à droite de ce registre, tout |
en faisant Control+Z. |
en faisant Control+Z. |
||
− | Les chiffres ont |
+ | Les chiffres ont changé! D'abord le registre A7 ne contient plus |
− | le |
+ | le même nombre. Celui qui s'y trouve actuellement est en effet |
− | plus petit que le |
+ | plus petit que le précédent. Notons que cette différence est de 4. |
− | L'adresse de la pile a donc |
+ | L'adresse de la pile a donc été décrémentée de 4. De plus des |
− | chiffres ont |
+ | chiffres ont été placés dans la pile (on les voit à droite du |
− | registre A7). Or, regardez bien le nombre qui est |
+ | registre A7). Or, regardez bien le nombre qui est à gauche de |
− | l'instruction MOVE.L #0,D0 de notre programme, c'est- |
+ | l'instruction MOVE.L #0,D0 de notre programme, c'est-à-dire |
− | l'adresse |
+ | 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 |
+ | 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 |
le changement d'adresse de la pile de 4. En effet une adresse est |
||
− | + | codée sur 4 octets ! |
|
− | Note: |
+ | Note: étant donné que nous parlons de pile, on dit plus souvent |
− | que les |
+ | que les données sont mises sur la pile et moins souvent dans la |
pile. |
pile. |
||
Continuons notre programme avec Control+Z. Nous sommes maintenant |
Continuons notre programme avec Control+Z. Nous sommes maintenant |
||
− | dans la sous-routine. |
+ | 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 |
truction qui va nous faire "remonter". Elle se lit RETURN FROM SUB |
||
ROUTINE. |
ROUTINE. |
||
− | Observons A7 (sa valeur mais aussi le contenu du 'tube' |
+ | Observons A7 (sa valeur mais aussi le contenu du 'tube' à cette |
− | adresse) et faisons un pas (Control+Z). L'adresse de retour a |
+ | 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. |
nant sur MOVE.L #0,D0. |
||
Line 242: | Line 243: | ||
RTS |
RTS |
||
− | Assemblez puis |
+ | Assemblez puis débuggez. Avancez pas à pas: D0 prend la valeur |
$12345678 D1 la valeur AAAAAAAA, puis nous partons vers la subrou- |
$12345678 D1 la valeur AAAAAAAA, puis nous partons vers la subrou- |
||
tine AJOUTE. |
tine AJOUTE. |
||
Malheureusement celle-ci utilise D1 et au retour nous constatons |
Malheureusement celle-ci utilise D1 et au retour nous constatons |
||
− | que celui-ci ne contient plus AAAAAAAA. En effet le branchement |
+ | que celui-ci ne contient plus AAAAAAAA. En effet le branchement à |
une subroutine ne sauve rien d'autre que l'adresse de retour, et |
une subroutine ne sauve rien d'autre que l'adresse de retour, et |
||
en assembleur les variables locales et autres bidouilles de langa- |
en assembleur les variables locales et autres bidouilles de langa- |
||
− | ges |
+ | ges évolués n'existent pas! C'est donc à nous de sauver les regis- |
tres, et c'est ce que nous allons faire maintenant. |
tres, et c'est ce que nous allons faire maintenant. |
||
Note: le registre A7 contenant l'adresse du sommet de la pile |
Note: le registre A7 contenant l'adresse du sommet de la pile |
||
− | (cette adresse variant bien |
+ | (cette adresse variant bien sûr avec l'empilage et le dépilage), |
− | on peut |
+ | on peut considérer cette adresse comme un doigt indiquant perpé- |
tuellement le sommet de la pile. Pour cette raison le registre A7 |
tuellement le sommet de la pile. Pour cette raison le registre A7 |
||
− | est aussi |
+ | est aussi appelé pointeur de pile. Comme toujours nous utiliserons |
− | le vocabulaire anglo-saxon, et nous dirons Stack Pointer, en |
+ | 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 |
+ | remplacerons désormais A7 par SP (qui ne se lit pas "èss-pé" mais |
bien STACK POINTER!!!). |
bien STACK POINTER!!!). |
||
− | Imaginons que nous voulions sauvegarder D0 |
+ | Imaginons que nous voulions sauvegarder D0 à l'entrée de la su- |
broutine: |
broutine: |
||
− | Il ne faudra pas oublier de le |
+ | Il ne faudra pas oublier de le récupérer à la |
− | sortie! |
+ | sortie! Déplaçons donc le contenu de D0 vers la pile. Essayons |
− | MOVE.L D0,SP et |
+ | 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. |
dans A7, malheureusement ce n'est pas ce que nous voulons faire. |
||
− | En effet nous |
+ | En effet nous désirons mettre le contenu de D0 DANS le tube, à |
− | l'endroit |
+ | l'endroit indiqué par A7 (donc SP). |
− | Ceci va se faire avec MOVE.L D0,(SP) ,les |
+ | Ceci va se faire avec MOVE.L D0,(SP) ,les parenthèses indiquant |
− | que la source de l' |
+ | que la source de l'opération c'est l'intérieur du tube. |
Effacez le programme actuel et tapez le suivant. |
Effacez le programme actuel et tapez le suivant. |
||
Line 282: | Line 283: | ||
MOVE.W D0,(A1) |
MOVE.W D0,(A1) |
||
− | Assemblez puis comme d'habitude |
+ | Assemblez puis comme d'habitude débuggez. D0 prend la valeur |
− | $12345678, puis D0 est |
+ | $12345678, puis D0 est transféré dans sa totalité (à cause du .L |
− | qui indique que l' |
+ | qui indique que l'opération se passe sur un mot long) à l'adresse |
− | qui est |
+ | qui est notée dans A0, ensuite le poids faible de D0 est transféré |
− | dans le tube |
+ | dans le tube à l'adresse notée en A1. Pour le vérifier, vous |
− | pouvez activer la |
+ | pouvez activer la fenêtre 3 et demander à placer l'adresse notée |
− | dans A0 en haut de cette |
+ | dans A0 en haut de cette fenêtre, et vous constaterez qu'effecti- |
vement la valeur de D0 se trouve bien dans le 'tube'. |
vement la valeur de D0 se trouve bien dans le 'tube'. |
||
Nous allons donc utiliser ce type de transfert pour sauvegarder D0 |
Nous allons donc utiliser ce type de transfert pour sauvegarder D0 |
||
− | Mais |
+ | 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- |
le contenu du long mot D0 dans le tube, mais si nous voulons pla- |
||
− | cer une autre valeur sur la pile, celle-ci va |
+ | 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 |
+ | (donc A7) ne va pas être modifiée, ce qui devrait être le cas. |
− | Nous allons donc |
+ | Nous allons donc réaliser le transfert différemment (en fait nous |
− | allons encore |
+ | allons encore améliorer notre vocabulaire, puisque nous allons |
parler maintenant de type ou de mode d'adressage). |
parler maintenant de type ou de mode d'adressage). |
||
Line 306: | Line 307: | ||
MOVE.L D0,-(SP) |
MOVE.L D0,-(SP) |
||
− | C'est le mode d'adressage avec |
+ | C'est le mode d'adressage avec pré-décrémentation. Derrière ce vo- |
− | cabulaire pompeux se cache toute une suite d' |
+ | cabulaire pompeux se cache toute une suite d'événements. En une |
seul instruction, nous diminuons l'adresse du pointeur de pile de |
seul instruction, nous diminuons l'adresse du pointeur de pile de |
||
− | 4 (puisque dans notre exemple nous voulions |
+ | 4 (puisque dans notre exemple nous voulions transférer un long mot |
− | donc 4 octets), et nous |
+ | donc 4 octets), et nous plaçons en mémoire à cette adresse le long |
mot D0. |
mot D0. |
||
− | Pour |
+ | Pour récupérer D0, c'est-à-dire dépiler, il faudra faire: |
MOVE.L D0,(SP)+ |
MOVE.L D0,(SP)+ |
||
− | Comme nous avions |
+ | Comme nous avions décrémenté le pointeur de pile pour ensuite dé- |
− | poser D0 |
+ | 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 |
suite de modifier le pointeur de pile dans l'autre sens, pour |
||
− | qu'il retrouve son ancienne position. Notons que dans le cas |
+ | qu'il retrouve son ancienne position. Notons que dans le cas pré- |
− | sent, et si nous nous contentons de |
+ | sent, et si nous nous contentons de réfléchir très sommairement, |
− | il aurait |
+ | 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 |
+ | 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 |
+ | pilage précédent. |
− | + | Vérifions tout cela avec l'exemple suivant: |
|
MOVE.L #$12345678,D0 valeur dans D0 |
MOVE.L #$12345678,D0 valeur dans D0 |
||
MOVE.W #$AAAA,D1 valeur dans D1 |
MOVE.W #$AAAA,D1 valeur dans D1 |
||
MOVE.L D0,-(SP) sauve D0.L sur la pile |
MOVE.L D0,-(SP) sauve D0.L sur la pile |
||
MOVE.W D1,-(SP) idem D1 mais en word |
MOVE.W D1,-(SP) idem D1 mais en word |
||
− | MOVE.L #0,D0 remet D0 |
+ | MOVE.L #0,D0 remet D0 à 0 |
MOVE.W #0,D1 et D1 aussi |
MOVE.W #0,D1 et D1 aussi |
||
− | MOVE.W D1,(SP)+ |
+ | MOVE.W D1,(SP)+ récupère D1 (word) |
MOVE.L D0,-(SP) puis D0 |
MOVE.L D0,-(SP) puis D0 |
||
− | Assemblez puis faites |
+ | Assemblez puis faites défiler ce programme pas à pas sous MONST. |
− | Notez plusieurs choses: tout d'abord des commentaires ont |
+ | 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. |
randes pour que l'assembleur sache qu'il s'agit de commentaires. |
||
− | Si vous |
+ | 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 |
sur celle-ci il n'y aura rien d'autre que ce commentaire), vous |
||
− | devez le faire |
+ | devez le faire précéder du caractère étoile ou d'un point virgule. |
− | Seconde chose, nous avions |
+ | 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 |
+ | et aux tailles de ce que nous empilons, afin de pouvoir dépiler |
− | les |
+ | les mêmes tailles, dans l'ordre inverse de l'empilage. |
Voici un dernier exemple. |
Voici un dernier exemple. |
||
Line 364: | Line 365: | ||
RTS |
RTS |
||
− | Assemblez puis suivez le |
+ | Assemblez puis suivez le déroulement sous MONST en étudiant bien |
− | le |
+ | 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 |
+ | 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. |
programme remonte. |
||
Maintenant, provoquons une erreur, une toute petite erreur mais |
Maintenant, provoquons une erreur, une toute petite erreur mais |
||
− | qui sera fatale |
+ | 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 |
+ | MOVE.L (SP)+,D0, commettons une faute de frappe et tapons à la |
place MOVE.W (SP)+,D0. |
place MOVE.W (SP)+,D0. |
||
− | Assemblez et suivez pas |
+ | Assemblez et suivez pas à pas. Au moment de la sauvegarde de D0, |
− | ce sont bien 4 octets qui vont |
+ | ce sont bien 4 octets qui vont être placés sur la pile, modifiant |
− | celle-ci d'autant. Malheureusement la |
+ | celle-ci d'autant. Malheureusement la récupération ne va re-mo- |
− | difier cette pile que de 2 octets. Au moment |
+ | difier cette pile que de 2 octets. Au moment où l'instruction RTS |
− | va essayer de |
+ | va essayer de récupérer l'adresse de retour, le pointeur de pile |
− | sera faux de 2 octets par rapport |
+ | 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 |
+ | ment cette adresse de retour, et celui-ci va se faire à une |
adresse fausse. En conclusion: prudence et rigueur!!!!!! |
adresse fausse. En conclusion: prudence et rigueur!!!!!! |
||
− | Nous venons donc de voir que la pile |
+ | Nous venons donc de voir que la pile était utilisée par le 68000 |
− | pour certaines instructions, et qu'elle |
+ | pour certaines instructions, et qu'elle était bien commode comme |
sauvegarde. |
sauvegarde. |
||
− | Il est aussi possible de l'utiliser pour transmettre des |
+ | Il est aussi possible de l'utiliser pour transmettre des données, |
c'est ce que nous allons voir pour conclure ce chapitre. |
c'est ce que nous allons voir pour conclure ce chapitre. |
||
− | + | Problème: Notre programme principal utilise les registres A0 à A6 |
|
− | et D0 |
+ | et D0 à D6. Il va appeler une subroutine destinée à additionner 2 |
− | nombres et |
+ | nombres et à retourner le résultat dans D7. Il faudra donc utili- |
ser 2 registres par exemple D0 et D1 pour travailler dans notre |
ser 2 registres par exemple D0 et D1 pour travailler dans notre |
||
− | routine, et donc les sauvegarder |
+ | routine, et donc les sauvegarder à l'entrée de celle-ci. |
− | Voici le |
+ | Voici le début du programme. |
MOVE.L #$11111111,D0 |
MOVE.L #$11111111,D0 |
||
Line 408: | Line 409: | ||
Les 7 premiers registres sont remplis avec des valeurs bidons, |
Les 7 premiers registres sont remplis avec des valeurs bidons, |
||
− | juste pour nous permettre de |
+ | juste pour nous permettre de vérifier leurs éventuelles modifica- |
tions. |
tions. |
||
− | Maintenant il faut placer les 2 nombres que nous |
+ | Maintenant il faut placer les 2 nombres que nous désirions addi- |
− | tionner, dans un endroit tel qu'ils pourront |
+ | tionner, dans un endroit tel qu'ils pourront être récupérés par la |
− | routine d'addition. |
+ | routine d'addition. Plaçons donc ces 2 nombres sur la pile. |
MOVE.L #$12345678,-(SP) |
MOVE.L #$12345678,-(SP) |
||
Line 419: | Line 420: | ||
BSR AJOUTE et en route ! |
BSR AJOUTE et en route ! |
||
− | + | Rédigeons maintenant notre subroutine, afin de suivre l'ordre de |
|
travail du 68000. |
travail du 68000. |
||
De quoi aurons nous besoin dans cette routine ? |
De quoi aurons nous besoin dans cette routine ? |
||
− | De D0 et de D1 qui vont recevoir les nombres |
+ | De D0 et de D1 qui vont recevoir les nombres empilés et qui |
− | vont nous servir au calcul. Il va nous falloir |
+ | vont nous servir au calcul. Il va nous falloir également un regis- |
− | tre d'adresse. En effet, lorsque nous allons |
+ | 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 |
modifier le pointeur de pile, or nous venons d'effectuer un BSR le |
||
− | 68000 a donc |
+ | 68000 a donc empilé l'adresse de retour sur la pile, et modifier |
celle-ci va compromettre le retour! Nous allons donc copier |
celle-ci va compromettre le retour! Nous allons donc copier |
||
l'adresse de la pile dans A0, et utiliser cette copie. |
l'adresse de la pile dans A0, et utiliser cette copie. |
||
− | Note: j'ai |
+ | Note: j'ai décidé d'utiliser D0, D1 et A0 mais n'importe quel au- |
tre registre aurait tout aussi bien convenu. |
tre registre aurait tout aussi bien convenu. |
||
− | + | Commençons donc par sauver nos 3 registres. |
|
Cela pourrait se faire par: |
Cela pourrait se faire par: |
||
Line 445: | Line 446: | ||
Note: je rappelle que cela se lit move long! |
Note: je rappelle que cela se lit move long! |
||
− | Mais le 68000 |
+ | Mais le 68000 possède une instruction très utile dans un pareil |
− | cas, qui permet de |
+ | cas, qui permet de transférer plusieurs registres d'un coup. |
Nous allons donc faire: |
Nous allons donc faire: |
||
Line 454: | Line 455: | ||
Ce qui se lit: move multiple registers. |
Ce qui se lit: move multiple registers. |
||
− | Si nous devions |
+ | Si nous devions transférer de D0 à D5 nous aurions fait : |
MOVEM.L D0-D5,-(SP) |
MOVEM.L D0-D5,-(SP) |
||
− | et, pour |
+ | et, pour transférer tous les registres d'un seul coup: |
MOVEM.L D0-D7/a0-A6,-(SP) Compris? |
MOVEM.L D0-D7/a0-A6,-(SP) Compris? |
||
Line 467: | Line 468: | ||
MOVE.L A7,A0 transfert du registre A7 vers A0 |
MOVE.L A7,A0 transfert du registre A7 vers A0 |
||
− | Maintenant nous allons |
+ | Maintenant nous allons récupérer les 2 nombres que nous avions em- |
− | + | pilé avant l'instruction BSR. |
|
− | Imaginons ce qui s'est |
+ | 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' |
+ | 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! |
pas! |
||
− | Faire un petit dessin ou de placer des |
+ | Faire un petit dessin ou de placer des pièces sur votre bureau |
− | pour vous aider |
+ | pour vous aider à comprendre est une excellente chose. Bien sou- |
− | vent les manipulations de |
+ | vent les manipulations de mémoire ont tendance à devenir abstrai- |
tes et un petit dessin arrange bien des choses!) |
tes et un petit dessin arrange bien des choses!) |
||
− | Nous avons |
+ | 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 |
+ | 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 |
que nous avons fait -(SP). Le pointeur de pile remonte donc le |
||
− | long du tube. Nous avons ensuite |
+ | 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 |
+ | tiquement par le 68000 afin d'y déposer l'adresse de retour (4 oc- |
tets). |
tets). |
||
Est-ce tout? Non car une fois rendu dans la subroutine nous avons |
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). |
3 fois 4 octets soit 12 octets (bytes). |
||
Notre copie de A7 qui est en A0 ne pointe donc pas sur nos 2 nom- |
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 |
+ | bres mais beaucoup plus loin. Le nombre que nous avons placé en |
− | second sur la pile est donc |
+ | 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 |
calcul: 1BSR, + 12 bytes de sauvegarde cela fait bien 16 bytes) et |
||
− | le nombre |
+ | le nombre placé en premier sur la pile suit son copain et se |
− | trouve donc |
+ | trouve donc à 20 bytes d'ici, en vertu toujours du principe de la |
− | pile: le dernier |
+ | pile: le dernier entré, c'est le premier sorti. |
− | Nous pouvons donc dire que $23456 est |
+ | Nous pouvons donc dire que $23456 est à A0 décalé de 16 et que |
− | $12345678 est |
+ | $12345678 est à A0 décalé de 20. |
− | Pour |
+ | Pour récupérer ces 2 nombres plusieurs actions sont possibles: |
− | 1) ajouter 16 |
+ | 1) ajouter 16 à l'adresse de A0 puis récupérer. |
Une addition d'adresse se fait par ADDA (add adress). |
Une addition d'adresse se fait par ADDA (add adress). |
||
Line 515: | Line 516: | ||
ADDA.L #16,A0 |
ADDA.L #16,A0 |
||
− | A0 pointe donc maintenant sur $23456, |
+ | A0 pointe donc maintenant sur $23456, récupérons donc ce nombre et |
− | profitons du mode d'adressage pour avancer l'adresse |
+ | profitons du mode d'adressage pour avancer l'adresse indiquée dans |
− | A0 et ainsi tout de suite |
+ | A0 et ainsi tout de suite être prêt pour récupérer l'autre nombre. |
MOVE.L A0)+,D0 |
MOVE.L A0)+,D0 |
||
− | L'adresse ayant |
+ | L'adresse ayant été augmentée nous pouvons donc récupérer la |
suite: |
suite: |
||
MOVE.L (A0)+,D1 |
MOVE.L (A0)+,D1 |
||
− | 2) Autre |
+ | 2) Autre méthode, utilisant un autre mode d'adressage: |
− | La |
+ | La méthode précédente présente un inconvénient: après le ADDA, A0 |
− | est |
+ | est modifié et si nous voulions garder cette adresse, il aurait |
fallu le sauvegarder. |
fallu le sauvegarder. |
||
− | Ou bien nous aurions pu ajouter le |
+ | 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 |
+ | sont état de départ. |
− | Autre |
+ | Autre méthode donc, indiquer dans l'adressage le décalage à appli- |
quer. Cela se fait par: |
quer. Cela se fait par: |
||
Line 539: | Line 540: | ||
MOVE.L 20(A0),D1 |
MOVE.L 20(A0),D1 |
||
− | Cela permet de pointer sur le |
+ | 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 |
+ | 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 #$11111111,D0 initialisation de D0 |
||
Line 555: | Line 556: | ||
MOVE.L #$00023456,-(SP) passage nombre 2 dans la pile |
MOVE.L #$00023456,-(SP) passage nombre 2 dans la pile |
||
BSR AJOUTE et en route ! |
BSR AJOUTE et en route ! |
||
− | MOVE.L D7,D0 transfert du |
+ | MOVE.L D7,D0 transfert du résultat pour voir.. |
Line 561: | Line 562: | ||
AJOUTE MOVEM.L D0-D1/A0,-(SP) sauvegarde |
AJOUTE MOVEM.L D0-D1/A0,-(SP) sauvegarde |
||
MOVE.L A7,A0 copie de SP en A0 |
MOVE.L A7,A0 copie de SP en A0 |
||
− | MOVE.L 16(A0),D0 |
+ | MOVE.L 16(A0),D0 récupère 23456 et le met en D0 |
− | MOVE.L 20(A0),D1 |
+ | MOVE.L 20(A0),D1 récupère 12345678 en D1 |
ADD.L D0,D1 addition |
ADD.L D0,D1 addition |
||
− | MOVE.L D1,D7 transfert du |
+ | MOVE.L D1,D7 transfert du résultat |
− | MOVEM.L (SP)+,D0-D1/A0 |
+ | MOVEM.L (SP)+,D0-D1/A0 récupération |
RTS et retour |
RTS et retour |
||
* Note: ce programme n'ayant pas de fin 'normale', |
* Note: ce programme n'ayant pas de fin 'normale', |
||
lorsque vous* serez rendu au retour de la subroutine |
lorsque vous* serez rendu au retour de la subroutine |
||
− | c'est- |
+ | c'est-à-dire après la ligne" MOVE.L D7,D0 ", quittez |
le avec Control+C, Assemblez et suivez bien TOUT le |
le avec Control+C, Assemblez et suivez bien TOUT le |
||
− | + | déroulement. |
|
− | Bien |
+ | Bien sûr, il aurait été possible de faire cela tout différemment. |
− | Par exemple nous aurions pu |
+ | Par exemple nous aurions pu éviter de travailler avec A0. En effet |
− | 16(A0) et 20(A0) ne modifiant pas A0, il aurait |
+ | 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 |
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' |
+ | et $12345678 en D1 puis de faire ADD.L D1,D7 afin d'éviter la |
− | sauvegarde de D0 (qui aurait |
+ | sauvegarde de D0 (qui aurait été inutilisée), et le transfert D1 |
− | vers D7 qui n'aurait alors pas eu lieu d' |
+ | vers D7 qui n'aurait alors pas eu lieu d'être. De même nous au- |
− | rions pu retourner le |
+ | rions pu retourner le résultat par la pile au lieu de le faire par |
D7. |
D7. |
||
Line 589: | Line 590: | ||
Pour terminer, un petit exercice. Relancer ce petit programme et |
Pour terminer, un petit exercice. Relancer ce petit programme et |
||
analysez PARFAITEMENT TOUT ce qui s'y passe. Quelque chose ne va |
analysez PARFAITEMENT TOUT ce qui s'y passe. Quelque chose ne va |
||
− | pas ! Je vous aide en disant qu'il s'agit bien |
+ | 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 |
+ | Cherchez et essayez de trouver comment faire pour arranger ça. |
− | La |
+ | 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!!! |
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 |
Bon, le cours sur la pile se termine ici. Ce fut un peu long mais |
||
− | je pense, pas trop |
+ | 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 |
+ | 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 |
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! |
|
+ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
</pre> |
</pre> |
||
Back to [[ASM_Tutorial]] |
Back to [[ASM_Tutorial]] |
Latest revision as of 23:19, 16 December 2023
****************************************************************** * * * 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 AJOUTE 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 signal que vous êtes pres- que à la moitié du cours...
Back to ASM_Tutorial