COURS206.TXT/fr: Difference between revisions

From Atari Wiki
Jump to navigation Jump to search
No edit summary
(Replacing content with updated version)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
  +
{{Languages|COURS206.TXT}}
 
<pre>
 
<pre>
 
******************************************************************
 
******************************************************************
Line 4: Line 5:
 
* COURS D'ASSEMBLEUR 68000 SUR ATARI ST *
 
* COURS D'ASSEMBLEUR 68000 SUR ATARI ST *
 
* *
 
* *
* par Le F�roce Lapin (from 44E) *
+
* par Le Féroce Lapin (from 44E) *
 
* *
 
* *
* Seconde s�rie *
+
* Seconde série *
 
* *
 
* *
* Cours num�ro 6 *
+
* Cours numéro 6 *
 
******************************************************************
 
******************************************************************
   
Line 14: Line 15:
 
LES AUTO-MODIFICATIONS
 
LES AUTO-MODIFICATIONS
   
Autre chose simple utiliser et qui facilite beaucoup la program-
+
Autre chose simple à utiliser et qui facilite beaucoup la program-
 
mation: les programmes auto-modifiables. Comme tous les sujets
 
mation: les programmes auto-modifiables. Comme tous les sujets
abord�s jusqu'ici, celui n'est pas compliqu� mais demande un peu
+
abordés jusqu'ici, celui n'est pas compliqué mais demande un peu
d'attention. Je dois cependant avouer que le premi�re fois que
+
d'attention. Je dois cependant avouer que le première fois que
j'ai rencontr� une telle chose dans un listing, de nombreuses heu-
+
j'ai rencontré une telle chose dans un listing, de nombreuses heu-
res m'ont �t� n�cessaires avant de comprendre ! La principale dif-
+
res m'ont été nécessaires avant de comprendre ! La principale dif-
ficult� r�sidant non pas dans la compr�hension du sujet lui-m�me
+
ficulté résidant non pas dans la compréhension du sujet lui-même
mais plut�t dans le choix de la m�thode d'explication, j'esp�re
+
mais plutôt dans le choix de la méthode d'explication, j'espère
 
que celle-ci vous donnera satisfaction!
 
que celle-ci vous donnera satisfaction!
   
Il est tout fait possible d'imaginer une addition avec des va-
+
Il est tout à fait possible d'imaginer une addition avec des va-
riables. Par exemple A=1, B=2 pour une op�ration du genre A+B=C
+
riables. Par exemple A=1, B=2 pour une opération du genre A+B=C
Nous imaginons �galement sans mal que les valeurs de A et B puis-
+
Nous imaginons également sans mal que les valeurs de A et B puis-
 
sent changer en cours de programme pour devenir par exemple A=2 et
 
sent changer en cours de programme pour devenir par exemple A=2 et
B=3 ce qui laisse notre op�ration A+B=C toujours aussi valable.
+
B=3 ce qui laisse notre opération A+B=C toujours aussi valable.
Mais, comment faire pour que cette op�ration A+B=C devienne tout
+
Mais, comment faire pour que cette opération A+B=C devienne tout à
 
coup A-B=C ou encore A/B=C ?
 
coup A-B=C ou encore A/B=C ?
   
L� se fait toute la diff�rence entre un langage �volu� et l'assem-
+
se fait toute la différence entre un langage évolué et l'assem-
 
bleur. Nous avons vu, dans les premiers cours, que l'assembleur ne
 
bleur. Nous avons vu, dans les premiers cours, que l'assembleur ne
faisait que traduire en chiffres les instructions. A la diff�rence
+
faisait que traduire en chiffres les instructions. A la différence
 
des compilateurs qui 'arrangent' les instructions, l'assembleur ne
 
des compilateurs qui 'arrangent' les instructions, l'assembleur ne
r�alise qu'une traduction, instruction par instruction. Nous nous
+
réalise qu'une traduction, instruction par instruction. Nous nous
retrouvons donc avec une suite de chiffres, ces chiffres �tant
+
retrouvons donc avec une suite de chiffres, ces chiffres étant
dans le 'tube'. Tout comme nous avons �crit dans le tube pour
+
dans le 'tube'. Tout comme nous avons écrit dans le tube pour
modifier des valeurs donn�es des variables, il est donc tout a
+
modifier des valeurs données à des variables, il est donc tout a
fait possible d'�crire dans le tube pour modifier les chiffres qui
+
fait possible d'écrire dans le tube pour modifier les chiffres qui
sont en fait des instructions. Il est �vident que la prudence
+
sont en fait des instructions. Il est évident que la prudence
s'impose car les chiffres que nous allons �crire doivent �tre
+
s'impose car les chiffres que nous allons écrire doivent être
 
reconnus par le 68000 comme une nouvelle instruction et non pas
 
reconnus par le 68000 comme une nouvelle instruction et non pas
comme n'importe quoi, ce qui conduirait une erreur. Voyons
+
comme n'importe quoi, ce qui conduirait à une erreur. Voyons
concr�tement un exemple simple.Nous avons une liste de lettres co-
+
concrètement un exemple simple.Nous avons une liste de lettres co-
d�e en word, et nous voulons afficher ces lettres les unes apr�s
+
dée en word, et nous voulons afficher ces lettres les unes après
 
les autres.
 
les autres.
   
Voici un programme r�alisant cette op�ration.
+
Voici un programme réalisant cette opération.
   
 
INCLUDE "B:\START.S"
 
INCLUDE "B:\START.S"
 
LEA TABLEAU,A6 dans A6 car GEMDOS n'y touche pas
 
LEA TABLEAU,A6 dans A6 car GEMDOS n'y touche pas
DEBUT MOVE.W (A6)+,D0 pr�l�ve le word
+
DEBUT MOVE.W (A6)+,D0 prélève le word
 
CMP.W #$FFFF,D0 c'est le flag de fin?
 
CMP.W #$FFFF,D0 c'est le flag de fin?
 
BEQ FIN oui, bye bye
 
BEQ FIN oui, bye bye
Line 76: Line 77:
   
 
Imaginons maintenant que cet affichage soit dans une subroutine,
 
Imaginons maintenant que cet affichage soit dans une subroutine,
et que nous voulions afficher une lettre chaque appel de cette
+
et que nous voulions afficher une lettre à chaque appel de cette
 
subroutine: On attend un appui sur une touche, si c'est 'espace',
 
subroutine: On attend un appui sur une touche, si c'est 'espace',
alors on s'en va, sinon on saute la routine qui affiche un ca-
+
alors on s'en va, sinon on saute à la routine qui affiche un ca-
ract�re puis revient. Voici un premier essai:
+
ractère puis revient. Voici un premier essai:
   
 
INCLUDE "B:\START.S"
 
INCLUDE "B:\START.S"
Line 94: Line 95:
 
*------------------------------*
 
*------------------------------*
 
AFFICHE LEA TABLEAU,A6 adresse du tableau
 
AFFICHE LEA TABLEAU,A6 adresse du tableau
MOVE.W A6)+,D0 pr�l�ve le word
+
MOVE.W A6)+,D0 prélève le word
 
MOVE.W D0,-(SP) le passe sur la pile
 
MOVE.W D0,-(SP) le passe sur la pile
 
MOVE.W #2,-(SP) pour l'afficher
 
MOVE.W #2,-(SP) pour l'afficher
Line 109: Line 110:
   
   
Assemblez et lancez le programme. Constatation: chaque appui sur
+
Assemblez et lancez le programme. Constatation: à chaque appui sur
 
une touche, on obtient un 'A' mais pas les autres lettres!!!
 
une touche, on obtient un 'A' mais pas les autres lettres!!!
Evidemment, puisqu' chaque fois que nous sautons dans notre su-
+
Evidemment, puisqu'à chaque fois que nous sautons dans notre su-
 
broutine AFFICHE, celle-ci recharge l'adresse du tableau. Le ca-
 
broutine AFFICHE, celle-ci recharge l'adresse du tableau. Le ca-
ract�re pr�lev� est donc toujours le premier. Pour �viter cela, il
+
ractère prélevé est donc toujours le premier. Pour éviter cela, il
faut donc cr�er un pointeur qui avancera dans ce tableau. Dans no-
+
faut donc créer un pointeur qui avancera dans ce tableau. Dans no-
 
tre exemple, il suffisait en fait de placer le LEA TABLEAU,A6 au
 
tre exemple, il suffisait en fait de placer le LEA TABLEAU,A6 au
d�but du programme. A6 n'�tant modifi� par personne, cela aurait
+
début du programme. A6 n'étant modifié par personne, cela aurait
fonctionn�.... jusqu'au 7�me appui sur une touche, A6 pointant
+
fonctionné.... jusqu'au 7ème appui sur une touche, A6 pointant
 
alors hors du tableau ! De plus, nous sommes ici pour apprendre et
 
alors hors du tableau ! De plus, nous sommes ici pour apprendre et
nous envisageons donc le cas o�, en dehors de la routine, tous les
+
nous envisageons donc le cas , en dehors de la routine, tous les
registres sont modifi�s! Impossible donc de garder A6 comme poin-
+
registres sont modifiés! Impossible donc de garder A6 comme poin-
teur. Voici donc la routine AFFICHE modifi�e:
+
teur. Voici donc la routine AFFICHE modifiée:
   
 
AFFICHE MOVEA.L PTN_TAB,A0
 
AFFICHE MOVEA.L PTN_TAB,A0
Line 137: Line 138:
 
RTS
 
RTS
   
De plus il faut rajouter apr�s le INCLUDE (donc avant le label
+
De plus il faut rajouter après le INCLUDE (donc avant le label
d�but)
+
début)
 
LEA TABLEAU,A0
 
LEA TABLEAU,A0
 
MOVE.L A0,PTN_TAB
 
MOVE.L A0,PTN_TAB
Line 145: Line 146:
 
PTN_TAB DS.L 1
 
PTN_TAB DS.L 1
   
Un peu d'analyse apr�s ces changements! Tout d'abord nous consta-
+
Un peu d'analyse après ces changements! Tout d'abord nous consta-
tons avec bonheur que �a marche! Au d�but nous mettons en place un
+
tons avec bonheur que ça marche! Au début nous mettons en place un
 
pointeur.
 
pointeur.
   
Line 152: Line 153:
 
MOVE.L A0,PTN_TAB et la sauve dans PTN_TAB
 
MOVE.L A0,PTN_TAB et la sauve dans PTN_TAB
   
Nous avons donc maintenant dans le tube en face de l'�tiquette
+
Nous avons donc maintenant dans le tube en face de l'étiquette
PTN_TAB un long mot, ce long mot �tant l'adresse du d�but du ta-
+
PTN_TAB un long mot, ce long mot étant l'adresse du début du ta-
bleau. Ensuite dans la routine, nous pr�levons cette adresse. Ici
+
bleau. Ensuite dans la routine, nous prélevons cette adresse. Ici
une petite remarque s'impose car la confusion est fr�quente: Si
+
une petite remarque s'impose car la confusion est fréquente: Si
 
nous avons:
 
nous avons:
   
Line 168: Line 169:
 
PTN_IMAG DC.L IMAGE
 
PTN_IMAG DC.L IMAGE
   
C'est--dire une �tiquette pour un long mot se trouvant �tre
+
C'est-à-dire une étiquette pour un long mot se trouvant être
l'adresse de l'image, en faisant LEA PTN_IMAGE,A0 nous ne r�cup�-
+
l'adresse de l'image, en faisant LEA PTN_IMAGE,A0 nous ne récupé-
 
rons pas en A0 l'adresse de l'image mais en fait l'adresse de
 
rons pas en A0 l'adresse de l'image mais en fait l'adresse de
l'adresse de l'image! Pour r�cup�rer directement un pointeur sur
+
l'adresse de l'image! Pour récupérer directement un pointeur sur
 
l'image il faut faire:
 
l'image il faut faire:
   
 
MOVEA.L PTN_IMAGE,A0
 
MOVEA.L PTN_IMAGE,A0
   
Cependant, pour r�cup�rer l'adresse du tableau il aurait �galement
+
Cependant, pour récupérer l'adresse du tableau il aurait également
�t� possible de faire:
+
été possible de faire:
   
 
MOVEA.L #TABLEAU,A0
 
MOVEA.L #TABLEAU,A0
   
 
Ceci dit, continuons notre exploration: Dans PTN_TAB nous avons
 
Ceci dit, continuons notre exploration: Dans PTN_TAB nous avons
donc l'adresse du d�but du tableau. Attente d'un appui touche, hop
+
donc l'adresse du début du tableau. Attente d'un appui touche, hop
 
on saute dans la routine. Transfert l'adresse contenue dans
 
on saute dans la routine. Transfert l'adresse contenue dans
PTN_TAB dans A0 puis on pr�l�ve le word contenu dans le tube
+
PTN_TAB dans A0 puis on prélève le word contenu dans le tube à
cette adresse et on le met en D0. Comme nous avons r�alis� cette
+
cette adresse et on le met en D0. Comme nous avons réalisé cette
op�ration avec (A0)+, A0 point donc maintenant sur le prochain
+
opération avec (A0)+, A0 point donc maintenant sur le prochain
word du tableau. Testons si le word pr�lev� est $FFFF, ce qui in-
+
word du tableau. Testons si le word prélevé est $FFFF, ce qui in-
diquerait la fin du tableau. Si ce n'est pas le cas, on saute
+
diquerait la fin du tableau. Si ce n'est pas le cas, on saute à
 
.ICI et on sauve la nouvelle valeur de A0 dans PTN_TAB.
 
.ICI et on sauve la nouvelle valeur de A0 dans PTN_TAB.
   
Si le word pr�lev� est $FFFF, on recharge PTN_TAB avec l'adresse
+
Si le word prélevé est $FFFF, on recharge PTN_TAB avec l'adresse
 
du haut du tableau, et c'est reparti comme en 14!!!
 
du haut du tableau, et c'est reparti comme en 14!!!
   
Ce syst�me de pointeur, tr�s fr�quemment utilis�, est simple d'em-
+
Ce système de pointeur, très fréquemment utilisé, est simple d'em-
ploi et bien commode! Voyons cependant une autre m�thode, plus
+
ploi et bien commode! Voyons cependant une autre méthode, plus
tordue! Supprimons tout d'abord la routine AFFICHE et rempla�ons
+
tordue! Supprimons tout d'abord la routine AFFICHE et remplaçons
 
la par la suivante:
 
la par la suivante:
   
Line 207: Line 208:
 
RTS
 
RTS
   
R�assemblons et lan�ons. Il est bien �vident que cela ne marche
+
Réassemblons et lançons. Il est bien évident que cela ne marche
plus puisqu' chaque appel de la routine, nous rechargeons A0 avec
+
plus puisqu'à chaque appel de la routine, nous rechargeons A0 avec
l'adresse du TABLEAU, donc le word pr�lev� sera toujours le pre-
+
l'adresse du TABLEAU, donc le word prélevé sera toujours le pre-
 
mier du tableau. Passons sous MONST avec Alt+D. Descendons sur le
 
mier du tableau. Passons sous MONST avec Alt+D. Descendons sur le
 
label AFFICHE. Nous trouvons en face MOVEA.L #TABLEAU,A0 etc....
 
label AFFICHE. Nous trouvons en face MOVEA.L #TABLEAU,A0 etc....
Quittons avec control+C puis r�assemblons, mais attention avant de
+
Quittons avec control+C puis réassemblons, mais attention avant de
 
cliquer sur 'assembler', jetons un coup d'oeil sur les options.
 
cliquer sur 'assembler', jetons un coup d'oeil sur les options.
Nous avons par d�faut DEBUG INFO indiquant Extend. Cela signifie
+
Nous avons par défaut DEBUG INFO indiquant Extend. Cela signifie
que les noms des labels vont �tre incorpor�s dans le programme.
+
que les noms des labels vont être incorporés dans le programme.
 
Cela nous permet de retrouver les noms de ces labels lorsque nous
 
Cela nous permet de retrouver les noms de ces labels lorsque nous
 
sommes sous MONST. Choisissons l'option NONE pour DEBUG INFO as-
 
sommes sous MONST. Choisissons l'option NONE pour DEBUG INFO as-
 
semblons et repassons sous MONST.
 
semblons et repassons sous MONST.
   
Surprise, les noms des labels ont disparu et sont remplac�s par
+
Surprise, les noms des labels ont disparu et sont remplacés par
des chiffres. C'est logique puisque, de toute fa�on, l'assembleur
+
des chiffres. C'est logique puisque, de toute façon, l'assembleur
 
traduit notre source en chiffres. Cherchons notre routine AFFI-
 
traduit notre source en chiffres. Cherchons notre routine AFFI-
CHAGE. C'est un peu plus dur puisque son �tiquette n'est plus vi-
+
CHAGE. C'est un peu plus dur puisque son étiquette n'est plus vi-
sible! Pour se rep�rer, on peut chercher au d�but (apr�s le start)
+
sible! Pour se repérer, on peut chercher au début (après le start)
CMP.W #$20,D0 qui est la comparaison avec la touche espace apr�s
+
CMP.W #$20,D0 qui est la comparaison avec la touche espace après
 
l'appui touche. Ensuite, un BEQ vers la fin et le BSR vers notre
 
l'appui touche. Ensuite, un BEQ vers la fin et le BSR vers notre
routine. Relevons l'adresse situ�e en face du BSR et allons-y. La
+
routine. Relevons l'adresse située en face du BSR et allons-y. La
premi�re ligne de notre routine c'est MOVEA.L #$XXXXXXX,A0 XXXXXXX
+
première ligne de notre routine c'est MOVEA.L #$XXXXXXX,A0 XXXXXXX
�tant l'adresse du tableau. Je rappelle que sur un 68000 le pro-
+
étant l'adresse du tableau. Je rappelle que sur un 68000 le pro-
gramme peut se trouver n'importe o� en m�moire, cette adresse sera
+
gramme peut se trouver n'importe en mémoire, cette adresse sera
donc diff�rente suivant les machines. Pour ma part c'est $924C6.
+
donc différente suivant les machines. Pour ma part c'est $924C6.
J'active la fen�tre 3 avec Alt+3 puis avec alt+a je demande la
+
J'active la fenêtre 3 avec Alt+3 puis avec alt+a je demande à la
fen�tre de se positionner sur cette adresse. MONST m'affiche au
+
fenêtre de se positionner sur cette adresse. MONST m'affiche au
 
centre les codes ASCII des lettres de mon tableau ($41,$42 etc...)
 
centre les codes ASCII des lettres de mon tableau ($41,$42 etc...)
et droite ces lettres en 'texte'.
+
et à droite ces lettres en 'texte'.
   
En avan�ant dans cette routine d'affichage, je vais donc mettre
+
En avançant dans cette routine d'affichage, je vais donc mettre
(pour moi) $924C6 en A0, cette adresse �tant celle pointant sur
+
(pour moi) $924C6 en A0, cette adresse étant celle pointant sur
le 'A' du tableau. Ce qui m'int�resserait, c'est que, la prochaine
+
le 'A' du tableau. Ce qui m'intéresserait, c'est que, la prochaine
 
fois, cela me permette de pointer sur le 'B'. Pour cela il
 
fois, cela me permette de pointer sur le 'B'. Pour cela il
 
faudrait avoir:
 
faudrait avoir:
Line 247: Line 248:
 
MOVEA.L #$924C8,A0 pour le 'B'.
 
MOVEA.L #$924C8,A0 pour le 'B'.
   
Les lettres �tant sous forme de word dans mon tableau il faut une
+
Les lettres étant sous forme de word dans mon tableau il faut une
 
avance de 2 !
 
avance de 2 !
   
Retournons dans la fen�tre 2, en face de ce MOVEA.L, regardons
+
Retournons dans la fenêtre 2, en face de ce MOVEA.L, regardons
l'adresse laquelle il se trouve (colonne de gauche), notons
+
l'adresse à laquelle il se trouve (colonne de gauche), notons
cette adresse, et notons �galement l'adresse de l'instruction sui-
+
cette adresse, et notons également l'adresse de l'instruction sui-
vante (MOVE.W (A0)+,D0). Activons la fen�tre 3, et pla�ons nous
+
vante (MOVE.W (A0)+,D0). Activons la fenêtre 3, et plaçons nous à
 
l'adresse du MOVEA.L.
 
l'adresse du MOVEA.L.
   
Line 259: Line 260:
 
MOVEA.L #$924C6,A0 je trouve 207C 0009 24C6
 
MOVEA.L #$924C6,A0 je trouve 207C 0009 24C6
   
J'en d�duis que ces 3 words constituent la repr�sentation de mon
+
J'en déduis que ces 3 words constituent la représentation de mon
 
instruction MOVEA.L, puisque l'adresse du word suivant correspond
 
instruction MOVEA.L, puisque l'adresse du word suivant correspond
celle de l'instruction suivante. Or, je retrouve dans ce codage,
+
à celle de l'instruction suivante. Or, je retrouve dans ce codage,
l'adresse de mon tableau. Avec un peu d'imagination, je con�ois
+
l'adresse de mon tableau. Avec un peu d'imagination, je conçois
ais�ment qu'il est possible d'�crire directement dans le 'tube' et
+
aisément qu'il est possible d'écrire directement dans le 'tube' et
 
par exemple de modifier le word qui a pour valeur actuelle 24C6.
 
par exemple de modifier le word qui a pour valeur actuelle 24C6.
 
Si je lui ajoute 2, mon instruction deviendra 207C 0009 24C8 ce
 
Si je lui ajoute 2, mon instruction deviendra 207C 0009 24C8 ce
qui reviendra MOVEA.L #$924C8,A0 et qui me fera pointer sur le
+
qui reviendra à MOVEA.L #$924C8,A0 et qui me fera pointer sur le
 
second word du tableau!!!!!!!!
 
second word du tableau!!!!!!!!
   
Line 284: Line 285:
 
RTS
 
RTS
   
Note: PTN_TAB ne nous sert plus, et de m�me le LEA tableau du
+
Note: PTN_TAB ne nous sert plus, et de même le LEA tableau du
d�but.
+
début.
   
 
Assemblez avec NONE en DEBUG INFO, puis passez sous MONST, faites
 
Assemblez avec NONE en DEBUG INFO, puis passez sous MONST, faites
avancer pas pas et regardez la ligne
+
avancer pas à pas et regardez la ligne
   
 
MOVEA.L #TABLEAU,A0 se modifier!
 
MOVEA.L #TABLEAU,A0 se modifier!
Line 294: Line 295:
 
Expliquons bien clairement ce qui se passe.
 
Expliquons bien clairement ce qui se passe.
   
Nous pla�ons TABLEAU en A0 puis nous pr�levons le word. Admettons
+
Nous plaçons TABLEAU en A0 puis nous prélevons le word. Admettons
tout d'abord qu'il ne s'agisse pas de $FFFF, nous sautons donc
+
tout d'abord qu'il ne s'agisse pas de $FFFF, nous sautons donc à
 
.ICI. Il faut donc ajouter 2 pour augmenter l'adresse et pointer
 
.ICI. Il faut donc ajouter 2 pour augmenter l'adresse et pointer
 
la prochaine fois sur la seconde lettre du tableau. Nous avons vu
 
la prochaine fois sur la seconde lettre du tableau. Nous avons vu
qu'en �tant cod�e la ligne MOVEA.L etc... tient sur 3 words donc 6
+
qu'en étant codée la ligne MOVEA.L etc... tient sur 3 words donc 6
bytes. L'ajout de 2 doit donc porter sur le 3�me word. Le d�but de
+
bytes. L'ajout de 2 doit donc porter sur le 3ème word. Le début de
 
ce word c'est le byte 4. Pour cette raison nous donnons comme des-
 
ce word c'est le byte 4. Pour cette raison nous donnons comme des-
 
tination de l'addition AFFICHE+4.
 
tination de l'addition AFFICHE+4.
   
Si nous avions pr�lev� $FFFF, il aurait fallu r�initialiser notre
+
Si nous avions prélevé $FFFF, il aurait fallu réinitialiser notre
 
ligne MOVEA.L avec
 
ligne MOVEA.L avec
   
Line 310: Line 311:
 
Pourquoi +2 ? Parce que l'adresse de tableau est un long mot et
 
Pourquoi +2 ? Parce que l'adresse de tableau est un long mot et
 
que, dans le codage de l'instruction, cela commence sur le second
 
que, dans le codage de l'instruction, cela commence sur le second
word. Il faut donc sauter un seul word c'est--dire 2 bytes.
+
word. Il faut donc sauter un seul word c'est-à-dire 2 bytes.
   
Dans le m�me ordre de chose, il est tout fait possible de modi-
+
Dans le même ordre de chose, il est tout à fait possible de modi-
fier plus profond�ment un programme. En voici un exemple flagrant.
+
fier plus profondément un programme. En voici un exemple flagrant.
(voir listing num�ro 4)
+
(voir listing numéro 4)
   
Sachant que l'instruction RTS (Return from subroutine) est cod�e
+
Sachant que l'instruction RTS (Return from subroutine) est codée
avec $4E75 et que l'instruction NOP (No operation) est cod�e par
+
avec $4E75 et que l'instruction NOP (No operation) est codée par
$4E71, en pla�ant un NOP ou un RTS, on change en fait la fin de la
+
$4E71, en plaçant un NOP ou un RTS, on change en fait la fin de la
routine. NOP ne fait rien du tout. C'est une op�ration qui est bi-
+
routine. NOP ne fait rien du tout. C'est une opération qui est bi-
don dans le sens o� rien ne change, mais cette instruction
+
don dans le sens rien ne change, mais cette instruction
consomme un peu de temps. Elle nous servira donc pour r�aliser des
+
consomme un peu de temps. Elle nous servira donc pour réaliser des
 
petites attentes (bien utile pour des effets graphiques par exem-
 
petites attentes (bien utile pour des effets graphiques par exem-
 
ple).
 
ple).
   
Suivez bien le d�roulement de ce programme sous MONST afin de voir
+
Suivez bien le déroulement de ce programme sous MONST afin de voir
 
les modifications se faire. Un cas plus complexe:
 
les modifications se faire. Un cas plus complexe:
   
Line 335: Line 336:
 
MOVE.W D1,D5
 
MOVE.W D1,D5
   
Apr�s assemblage de ce petit morceau de programme, passez sous
+
Après assemblage de ce petit morceau de programme, passez sous
MONST et jetez un coup d'oeil la fen�tre 3. En pointant sur
+
MONST et jetez un coup d'oeil à la fenêtre 3. En pointant sur
 
VARIANTE et en regardant les adresses en face des instructions, on
 
VARIANTE et en regardant les adresses en face des instructions, on
en d�duit que:
+
en déduit que:
   
 
ADD.W D0,D1 est converti en $D240
 
ADD.W D0,D1 est converti en $D240
Line 366: Line 367:
 
MOVE.L #$04410006,(A0)+
 
MOVE.L #$04410006,(A0)+
   
J'obtiendrai la premi�re version:
+
J'obtiendrai la première version:
 
ADD.W D0,D1;
 
ADD.W D0,D1;
 
MULU.W #3,D1;
 
MULU.W #3,D1;
Line 380: Line 381:
 
j'obtiendrai la seconde version!
 
j'obtiendrai la seconde version!
   
Essayez avec le programme ci-apr�s, en le suivant sous MONST:
+
Essayez avec le programme ci-après, en le suivant sous MONST:
 
Note: ce programme n'a pas de fin donc quitter avec Control+C:
 
Note: ce programme n'a pas de fin donc quitter avec Control+C:
   
Line 401: Line 402:
 
END
 
END
   
Remarques: Il est tout fait possible d'envisager plus de 2 ver-
+
Remarques: Il est tout à fait possible d'envisager plus de 2 ver-
sions d'une m�me partie de programme. Si les tailles de ces diff�-
+
sions d'une même partie de programme. Si les tailles de ces diffé-
rentes versions diff�rent, ce n'est pas grave car il est toujours
+
rentes versions diffèrent, ce n'est pas grave car il est toujours
 
possible de combler avec des NOP. Les applications de ce genre de
 
possible de combler avec des NOP. Les applications de ce genre de
'ruse' peuvent �tre assez nombreuses: raccourcissement de program-
+
'ruse' peuvent être assez nombreuses: raccourcissement de program-
mes, rapidit� (une routine devant �tre appel�e 15000 fois aura
+
mes, rapidité (une routine devant être appelée 15000 fois aura
tout int�r�t �tre modifi�e avant, au lieu d'y incorporer des
+
tout intérêt à être modifiée avant, au lieu d'y incorporer des
tests, par exemple), modifications al�atoires des routines de pro-
+
tests, par exemple), modifications aléatoires des routines de pro-
 
tection (un coup, j'en mets une en place la prochaine fois, j'en
 
tection (un coup, j'en mets une en place la prochaine fois, j'en
 
mettrai une autre...)....
 
mettrai une autre...)....
Line 414: Line 415:
 
Faites cependant bien attention, car une erreur d'un chiffre et le
 
Faites cependant bien attention, car une erreur d'un chiffre et le
 
nouveau code mis en place ne voudra plus rien dire du tout! Faites
 
nouveau code mis en place ne voudra plus rien dire du tout! Faites
�galement attention vos commentaires car l�, ils deviennent
+
également attention à vos commentaires car , ils deviennent
hyper importants, �tant donn� que le listing que vous avez sous
+
hyper importants, étant donné que le listing que vous avez sous
les yeux ne sera pas forc�ment celui qui sera ex�cut�!!!!!!!
+
les yeux ne sera pas forcément celui qui sera exécuté!!!!!!!
  +
 
</pre>
 
</pre>
 
Back to [[ASM_Tutorial]]
 
Back to [[ASM_Tutorial]]

Latest revision as of 00:17, 17 December 2023

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


   LES AUTO-MODIFICATIONS

   Autre chose simple à utiliser et qui facilite beaucoup la program-
   mation: les  programmes  auto-modifiables. Comme  tous  les sujets
   abordés  jusqu'ici, celui  n'est pas compliqué mais demande un peu
   d'attention. Je  dois  cependant  avouer  que le première fois que
   j'ai rencontré une telle chose dans un listing, de nombreuses heu-
   res m'ont été nécessaires avant de comprendre ! La principale dif-
   ficulté  résidant  non pas dans la compréhension du sujet lui-même
   mais  plutôt  dans  le choix de la méthode d'explication, j'espère
   que celle-ci vous donnera satisfaction!

   Il  est  tout à fait possible d'imaginer une addition avec des va-
   riables. Par  exemple  A=1, B=2 pour  une opération du genre A+B=C
   Nous  imaginons également sans mal que les valeurs de A et B puis-
   sent changer en cours de programme pour devenir par exemple A=2 et
   B=3 ce  qui  laisse  notre opération A+B=C toujours aussi valable.
   Mais, comment faire pour que cette opération A+B=C devienne tout à
   coup A-B=C ou encore A/B=C ?

   Là se fait toute la différence entre un langage évolué et l'assem-
   bleur. Nous avons vu, dans les premiers cours, que l'assembleur ne
   faisait que traduire en chiffres les instructions. A la différence
   des compilateurs qui 'arrangent' les instructions, l'assembleur ne
   réalise  qu'une traduction, instruction par instruction. Nous nous
   retrouvons  donc  avec  une  suite de chiffres, ces chiffres étant
   dans  le  'tube'. Tout  comme  nous  avons écrit dans le tube pour
   modifier  des  valeurs données à des variables, il est donc tout a
   fait possible d'écrire dans le tube pour modifier les chiffres qui
   sont  en  fait  des  instructions. Il  est évident que la prudence
   s'impose  car  les  chiffres  que  nous allons écrire doivent être
   reconnus  par  le  68000 comme une nouvelle instruction et non pas
   comme  n'importe  quoi, ce  qui  conduirait  à  une erreur. Voyons
   concrètement un exemple simple.Nous avons une liste de lettres co-
   dée  en  word, et nous voulons afficher ces lettres les unes après
   les autres.

   Voici un programme réalisant cette opération.

            INCLUDE   "B:\START.S"
            LEA       TABLEAU,A6     dans A6 car GEMDOS n'y touche pas
   DEBUT    MOVE.W    (A6)+,D0       prélève le word
            CMP.W     #$FFFF,D0      c'est le flag de fin?
            BEQ       FIN            oui, bye bye
            MOVE.W    D0,-(SP)       non, donc le passe sur la pile
            MOVE.W    #2,-(SP)       pour l'afficher
            TRAP      #1
            ADDQ.L    #4,SP
            MOVE.W    #7,-(SP)       attend un appui touche
            TRAP      #1
            ADDQ.L    #2,SP
            BRA       DEBUT          et on recommence
   FIN      MOVE.W    #0,-(SP)
            TRAP      #1
   *--------------------------------*
            SECTION DATA
   TABLEAU  DC.W      65,66,67,68,69,70,$FFFF
            SECTION BSS
            DS.L      100
   PILE     DS.L      1
            END


   Imaginons  maintenant  que cet affichage soit dans une subroutine,
   et  que  nous voulions afficher une lettre à chaque appel de cette
   subroutine: On  attend un appui sur une touche, si c'est 'espace',
   alors  on  s'en va, sinon on saute à la routine qui affiche un ca-
   ractère puis revient. Voici un premier essai:

            INCLUDE   "B:\START.S"
   DEBUT    MOVE.W    #7,-(SP)
            TRAP      #1
            ADDQ.L    #2,SP
            CMP.W     #" ",D0
            BEQ       FIN
            BSR       AFFICHE
            BRA       DEBUT

   FIN      MOVE.W    #0,-(SP)
            TRAP      #1
   *------------------------------*
   AFFICHE  LEA       TABLEAU,A6     adresse du tableau
            MOVE.W    A6)+,D0        prélève le word
            MOVE.W    D0,-(SP)       le passe sur la pile
            MOVE.W    #2,-(SP)       pour l'afficher
            TRAP      #1
            ADDQ.L    #4,SP
            RTS                      puis on remonte
   *--------------------------------*
            SECTION DATA
   TABLEAU  DC.W      65,66,67,68,69,70,$FFFF
            SECTION BSS
            DS.L      100
   PILE     DS.L      1
            END


   Assemblez et lancez le programme. Constatation: à chaque appui sur
   une  touche, on  obtient  un  'A' mais  pas  les autres lettres!!!
   Evidemment, puisqu'à  chaque  fois que nous sautons dans notre su-
   broutine  AFFICHE, celle-ci  recharge l'adresse du tableau. Le ca-
   ractère prélevé est donc toujours le premier. Pour éviter cela, il
   faut donc créer un pointeur qui avancera dans ce tableau. Dans no-
   tre  exemple, il  suffisait en fait de placer le LEA TABLEAU,A6 au
   début  du  programme. A6 n'étant modifié par personne, cela aurait
   fonctionné.... jusqu'au  7ème  appui  sur  une touche, A6 pointant
   alors hors du tableau ! De plus, nous sommes ici pour apprendre et
   nous envisageons donc le cas où, en dehors de la routine, tous les
   registres  sont modifiés! Impossible donc de garder A6 comme poin-
   teur. Voici donc la routine AFFICHE modifiée:

   AFFICHE  MOVEA.L   PTN_TAB,A0
            MOVE.W    (A0)+,D0
            CMP.W     #$FFFF,D0
            BNE       .ICI
            LEA       TABLEAU,A0
            MOVE.L    A0,PTN_TAB
            BRA       AFFICHE
   .ICI     MOVE.L    A0,PTN_TAB
            MOVE.W    D0,-(SP)
            MOVE.W    #2,-(SP)
            TRAP      #1
            ADDQ.L    #4,SP
            RTS

   De plus il faut rajouter après le INCLUDE (donc avant le label
   début)
            LEA       TABLEAU,A0
            MOVE.L    A0,PTN_TAB
   et en section BSS

   PTN_TAB  DS.L      1

   Un  peu d'analyse après ces changements! Tout d'abord nous consta-
   tons avec bonheur que ça marche! Au début nous mettons en place un
   pointeur.

            LEA       TABLEAU,A0     met l'adresse du tableau en A0
            MOVE.L    A0,PTN_TAB     et la sauve dans PTN_TAB

   Nous  avons  donc  maintenant  dans le tube en face de l'étiquette
   PTN_TAB  un  long mot, ce long mot étant l'adresse du début du ta-
   bleau. Ensuite  dans la routine, nous prélevons cette adresse. Ici
   une  petite  remarque  s'impose car la confusion est fréquente: Si
   nous avons:

   IMAGE    INCBIN    "A:\MAISON.PI1"

   et que nous voulons travailler avec cette image, nous ferons 

            LEA       IMAGE,A0

   A0 pointera alors sur l'image. Par contre si nous avons :

   PTN_IMAG DC.L      IMAGE

   C'est-à-dire  une  étiquette  pour  un  long  mot se trouvant être
   l'adresse  de l'image, en faisant LEA PTN_IMAGE,A0 nous ne récupé-
   rons  pas  en  A0 l'adresse  de  l'image mais en fait l'adresse de
   l'adresse  de  l'image! Pour récupérer directement un pointeur sur
   l'image il faut faire:

            MOVEA.L   PTN_IMAGE,A0

   Cependant, pour récupérer l'adresse du tableau il aurait également
   été possible de faire:

            MOVEA.L   #TABLEAU,A0

   Ceci  dit, continuons  notre  exploration: Dans PTN_TAB nous avons
   donc l'adresse du début du tableau. Attente d'un appui touche, hop
   on  saute  dans  la  routine. Transfert  l'adresse  contenue  dans
   PTN_TAB  dans  A0 puis  on  prélève le word contenu dans le tube à
   cette  adresse  et on le met en D0. Comme nous avons réalisé cette
   opération  avec  (A0)+, A0 point  donc  maintenant sur le prochain
   word  du tableau. Testons si le word prélevé est $FFFF, ce qui in-
   diquerait  la  fin  du tableau. Si ce n'est pas le cas, on saute à
   .ICI et on sauve la nouvelle valeur de A0 dans PTN_TAB.

   Si  le  word prélevé est $FFFF, on recharge PTN_TAB avec l'adresse
   du haut du tableau, et c'est reparti comme en 14!!!

   Ce système de pointeur, très fréquemment utilisé, est simple d'em-
   ploi  et  bien  commode! Voyons  cependant une autre méthode, plus
   tordue! Supprimons  tout  d'abord la routine AFFICHE et remplaçons
   la par la suivante:

   AFFICHE  MOVEA.L   #TABLEAU,A0
            MOVE.W    (A0)+,D0
            MOVE.W    D0,-(SP)
            MOVE.W    #2,-(SP)
            TRAP      #1
            ADDQ.L    #4,SP
            RTS

   Réassemblons  et  lançons. Il  est bien évident que cela ne marche
   plus puisqu'à chaque appel de la routine, nous rechargeons A0 avec
   l'adresse  du  TABLEAU, donc le word prélevé sera toujours le pre-
   mier  du tableau. Passons sous MONST avec Alt+D. Descendons sur le
   label AFFICHE. Nous  trouvons  en face MOVEA.L #TABLEAU,A0 etc....
   Quittons avec control+C puis réassemblons, mais attention avant de
   cliquer  sur  'assembler', jetons  un coup d'oeil sur les options.
   Nous  avons  par défaut DEBUG INFO indiquant Extend. Cela signifie
   que  les  noms  des labels vont être incorporés dans le programme.
   Cela  nous permet de retrouver les noms de ces labels lorsque nous
   sommes  sous  MONST. Choisissons l'option NONE pour DEBUG INFO as-
   semblons et repassons sous MONST. 

   Surprise,  les  noms  des labels ont disparu et sont remplacés par
   des  chiffres. C'est logique puisque, de toute façon, l'assembleur
   traduit  notre  source  en chiffres. Cherchons notre routine AFFI-
   CHAGE. C'est  un peu plus dur puisque son étiquette n'est plus vi-
   sible! Pour se repérer, on peut chercher au début (après le start)
   CMP.W  #$20,D0 qui  est la comparaison avec la touche espace après
   l'appui  touche. Ensuite, un  BEQ vers la fin et le BSR vers notre
   routine. Relevons  l'adresse située en face du BSR et allons-y. La
   première ligne de notre routine c'est MOVEA.L #$XXXXXXX,A0 XXXXXXX
   étant  l'adresse  du tableau. Je rappelle que sur un 68000 le pro-
   gramme peut se trouver n'importe où en mémoire, cette adresse sera
   donc  différente  suivant les machines. Pour ma part c'est $924C6.
   J'active  la  fenêtre 3 avec Alt+3 puis avec alt+a je demande à la
   fenêtre  de  se  positionner sur cette adresse. MONST m'affiche au
   centre les codes ASCII des lettres de mon tableau ($41,$42 etc...)
   et à droite ces lettres en 'texte'.

   En  avançant  dans  cette routine d'affichage, je vais donc mettre
   (pour  moi) $924C6 en  A0, cette  adresse étant celle pointant sur
   le 'A' du tableau. Ce qui m'intéresserait, c'est que, la prochaine
   fois, cela  me  permette  de  pointer  sur  le  'B'. Pour  cela il
   faudrait avoir:
            MOVEA.L   #$924C6,A0     pour le 'A'

   et ensuite 
            MOVEA.L   #$924C8,A0     pour le 'B'.

   Les  lettres étant sous forme de word dans mon tableau il faut une
   avance de 2 ! 

   Retournons  dans  la  fenêtre 2, en  face de ce MOVEA.L, regardons
   l'adresse  à  laquelle  il  se  trouve (colonne de gauche), notons
   cette adresse, et notons également l'adresse de l'instruction sui-
   vante  (MOVE.W (A0)+,D0). Activons la fenêtre 3, et plaçons nous à
   l'adresse du MOVEA.L.

   Dans mon cas, et puisque j'avais:
            MOVEA.L   #$924C6,A0     je trouve 207C 0009 24C6

   J'en  déduis  que ces 3 words constituent la représentation de mon
   instruction  MOVEA.L, puisque l'adresse du word suivant correspond
   à celle de l'instruction suivante. Or, je retrouve dans ce codage,
   l'adresse  de  mon  tableau. Avec un peu d'imagination, je conçois
   aisément qu'il est possible d'écrire directement dans le 'tube' et
   par  exemple  de modifier le word qui a pour valeur actuelle 24C6.
   Si  je  lui  ajoute 2, mon instruction deviendra 207C 0009 24C8 ce
   qui  reviendra  à MOVEA.L #$924C8,A0 et qui me fera pointer sur le
   second word du tableau!!!!!!!! 

   Voici donc la version auto-modifiable de la routine AFFICHE.

   AFFICHE MOVEA.L    #TABLEAU,A0
            MOVE.W    A0),D0
            CMP.W     #$FFFF,D0
            BNE       ICI
            MOVE.L    #TABLEAU,AFFICHE+2
            BRA       AFFICHE
   .ICI     ADD.W     #2,AFFICHE+4
            MOVE.W    D0,-(SP)
            MOVE.W    #2,-(SP)
            TRAP      #1
            ADDQ.L    #4,SP
            RTS

   Note: PTN_TAB  ne  nous  sert  plus, et  de même le LEA tableau du
   début.

   Assemblez  avec NONE en DEBUG INFO, puis passez sous MONST, faites
   avancer pas à pas et regardez la ligne

            MOVEA.L   #TABLEAU,A0    se modifier!

   Expliquons bien clairement ce qui se passe. 

   Nous  plaçons TABLEAU en A0 puis nous prélevons le word. Admettons
   tout  d'abord  qu'il ne s'agisse pas de $FFFF, nous sautons donc à
   .ICI. Il  faut  donc ajouter 2 pour augmenter l'adresse et pointer
   la  prochaine fois sur la seconde lettre du tableau. Nous avons vu
   qu'en étant codée la ligne MOVEA.L etc... tient sur 3 words donc 6
   bytes. L'ajout de 2 doit donc porter sur le 3ème word. Le début de
   ce word c'est le byte 4. Pour cette raison nous donnons comme des-
   tination de l'addition AFFICHE+4.

   Si  nous avions prélevé $FFFF, il aurait fallu réinitialiser notre
   ligne MOVEA.L avec

            MOVE.L    #TABLEAU,AFFICHE+2.

   Pourquoi  +2 ? Parce  que  l'adresse de tableau est un long mot et
   que, dans  le codage de l'instruction, cela commence sur le second
   word. Il faut donc sauter un seul word c'est-à-dire 2 bytes.

   Dans  le même ordre de chose, il est tout à fait possible de modi-
   fier plus profondément un programme. En voici un exemple flagrant.
   (voir listing numéro 4)

   Sachant  que  l'instruction RTS (Return from subroutine) est codée
   avec  $4E75 et  que l'instruction NOP (No operation) est codée par
   $4E71, en plaçant un NOP ou un RTS, on change en fait la fin de la
   routine. NOP ne fait rien du tout. C'est une opération qui est bi-
   don  dans  le  sens  où  rien  ne  change, mais  cette instruction
   consomme un peu de temps. Elle nous servira donc pour réaliser des
   petites  attentes (bien utile pour des effets graphiques par exem-
   ple).

   Suivez bien le déroulement de ce programme sous MONST afin de voir
   les modifications se faire. Un cas plus complexe:

            MOVE.W    #23,D0
            MOVE.W    #25,D1
   VARIANTE ADD.W     D0,D1
            MULU.W    #3,D1
            SUB.W     #6,D1
            MOVE.W    D1,D5

   Après  assemblage  de  ce  petit morceau de programme, passez sous
   MONST  et  jetez  un  coup  d'oeil à la fenêtre 3. En pointant sur
   VARIANTE et en regardant les adresses en face des instructions, on
   en déduit que:

            ADD.W     D0,D1     est converti en $D240
            MULU.W    #3,D1     est converti en $C2FC $0003
            SUB.W     #6,D1     est converti en $0441 $0006


   Si nous prenons maintenant:
            MOVE.W    #23,D0
            MOVE.W    #25,D1
   VARIANTE MULU.W    D0,D1
            SUB.W     #8,D1
            ADD.W     #4,D0
            MOVE.W    D1,D5

   Nous  assemblons,   passons  sous  MONST:

            MULU.W    D0,D1     est converti en $C2C0
            SUB.W     #8,D1     est converti en $0441 $0008
            ADD.W     #4,D0     est converti en $0640 $0004

   Donc, si dans un programme utilisant cette 'routine' je fais

            LEA       VARIANTE,A0
            MOVE.W    #$D240,(A0)+
            MOVE.L    #$C2FC0003,(A0)+
            MOVE.L    #$04410006,(A0)+

   J'obtiendrai  la  première version:
            ADD.W     D0,D1;
            MULU.W    #3,D1; 
            SUB.W     #6,D1

   alors que si je fais:

            LEA       VARIANTE,A0
            MOVE.W    #$C2C0,(A0)+
            MOVE.L    #$04410008,(A0)+
            MOVE.L    #$06400004,(A0)+

   j'obtiendrai la seconde version!

   Essayez  avec le programme ci-après, en le suivant sous MONST: 
   Note: ce programme n'a pas de fin donc quitter avec Control+C:

            LEA       VARIANTE,A0
            MOVE.W    #$D240,(A0)+
            MOVE.L    #$C2FC0003,(A0)+
            MOVE.L    #$04410006,(A0)+

            LEA       VARIANTE,A0
            MOVE.W    #$C2C0,(A0)+
            MOVE.L    #$04410008,(A0)+
            MOVE.L    #$06400004,(A0)+

            MOVE.W    #23,D0
            MOVE.W    #25,D1
   VARIANTE MULU.W    D0,D1
            SUB.W     #8,D1
            ADD.W     #4,D0
            MOVE.W    D1,D5
            END

   Remarques: Il  est tout à fait possible d'envisager plus de 2 ver-
   sions d'une même partie de programme. Si les tailles de ces diffé-
   rentes  versions diffèrent, ce n'est pas grave car il est toujours
   possible  de combler avec des NOP. Les applications de ce genre de
   'ruse' peuvent être assez nombreuses: raccourcissement de program-
   mes, rapidité  (une  routine  devant  être appelée 15000 fois aura
   tout  intérêt  à  être  modifiée avant, au lieu d'y incorporer des
   tests, par exemple), modifications aléatoires des routines de pro-
   tection  (un  coup, j'en mets une en place la prochaine fois, j'en
   mettrai une autre...)....

   Faites cependant bien attention, car une erreur d'un chiffre et le
   nouveau code mis en place ne voudra plus rien dire du tout! Faites
   également  attention  à  vos  commentaires  car là, ils deviennent
   hyper  importants, étant  donné  que le listing que vous avez sous
   les yeux ne sera pas forcément celui qui sera exécuté!!!!!!!

Back to ASM_Tutorial