COURS206.TXT/fr: Difference between revisions
Jump to navigation
Jump to search
(Created page with "<pre> ****************************************************************** * * * COURS D'ASSEMBL...") Â |
No edit summary |
||
Line 4: | Line 4: | ||
* COURS D'ASSEMBLEUR 68000 SUR ATARI ST * |
* COURS D'ASSEMBLEUR 68000 SUR ATARI ST * |
||
* * |
* * |
||
− | * par Le |
+ | * par Le F�roce Lapin (from 44E) * |
* * |
* * |
||
− | * Seconde |
+ | * Seconde s�rie * |
* * |
* * |
||
− | * Cours |
+ | * Cours num�ro 6 * |
****************************************************************** |
****************************************************************** |
||
Line 14: | Line 14: | ||
LES AUTO-MODIFICATIONS |
LES AUTO-MODIFICATIONS |
||
− | Autre chose simple |
+ | 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 |
+ | 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 |
+ | Il est tout � fait possible d'imaginer une addition avec des va- |
− | riables. Par exemple A=1, B=2 pour une |
+ | riables. Par exemple A=1, B=2 pour une op�ration du genre A+B=C |
− | Nous imaginons |
+ | 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 |
+ | B=3 ce qui laisse notre op�ration A+B=C toujours aussi valable. |
− | Mais, comment faire pour que cette |
+ | 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- |
||
− | 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 |
bleur. Nous avons vu, dans les premiers cours, que l'assembleur ne |
||
− | faisait que traduire en chiffres les instructions. A la |
+ | 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 |
+ | retrouvons donc avec une suite de chiffres, ces chiffres �tant |
− | dans le 'tube'. Tout comme nous avons |
+ | dans le 'tube'. Tout comme nous avons �crit dans le tube pour |
− | modifier des valeurs |
+ | modifier des valeurs donn�es � des variables, il est donc tout a |
− | fait possible d' |
+ | fait possible d'�crire dans le tube pour modifier les chiffres qui |
− | sont en fait des instructions. Il est |
+ | sont en fait des instructions. Il est �vident que la prudence |
− | s'impose car les chiffres que nous allons |
+ | 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 |
+ | 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 |
+ | 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 |
+ | 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 76: | ||
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 |
+ | 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 |
+ | 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 94: | ||
*------------------------------* |
*------------------------------* |
||
AFFICHE LEA TABLEAU,A6 adresse du tableau |
AFFICHE LEA TABLEAU,A6 adresse du tableau |
||
− | MOVE.W A6)+,D0 |
+ | 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 109: | ||
− | Assemblez et lancez le programme. Constatation: |
+ | 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' |
+ | 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 |
+ | nous envisageons donc le cas o�, en dehors de la routine, tous les |
− | registres sont |
+ | registres sont modifi�s! Impossible donc de garder A6 comme poin- |
− | teur. Voici donc la routine AFFICHE |
+ | teur. Voici donc la routine AFFICHE modifi�e: |
AFFICHE MOVEA.L PTN_TAB,A0 |
AFFICHE MOVEA.L PTN_TAB,A0 |
||
Line 137: | Line 137: | ||
RTS |
RTS |
||
− | De plus il faut rajouter |
+ | De plus il faut rajouter apr�s le INCLUDE (donc avant le label |
− | + | d�but) |
|
LEA TABLEAU,A0 |
LEA TABLEAU,A0 |
||
MOVE.L A0,PTN_TAB |
MOVE.L A0,PTN_TAB |
||
Line 145: | Line 145: | ||
PTN_TAB DS.L 1 |
PTN_TAB DS.L 1 |
||
− | Un peu d'analyse |
+ | Un peu d'analyse apr�s ces changements! Tout d'abord nous consta- |
− | tons avec bonheur que |
+ | tons avec bonheur que �a marche! Au d�but nous mettons en place un |
pointeur. |
pointeur. |
||
Line 152: | Line 152: | ||
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' |
+ | Nous avons donc maintenant dans le tube en face de l'�tiquette |
− | PTN_TAB un long mot, ce long mot |
+ | PTN_TAB un long mot, ce long mot �tant l'adresse du d�but du ta- |
− | bleau. Ensuite dans la routine, nous |
+ | bleau. Ensuite dans la routine, nous pr�levons cette adresse. Ici |
− | une petite remarque s'impose car la confusion est |
+ | une petite remarque s'impose car la confusion est fr�quente: Si |
nous avons: |
nous avons: |
||
Line 168: | Line 168: | ||
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 |
+ | 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 |
+ | 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 |
+ | 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 |
+ | 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 |
+ | 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 |
+ | 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 |
+ | 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 |
+ | 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 |
+ | ploi et bien commode! Voyons cependant une autre m�thode, plus |
− | tordue! Supprimons tout d'abord la routine AFFICHE et |
+ | tordue! Supprimons tout d'abord la routine AFFICHE et rempla�ons |
la par la suivante: |
la par la suivante: |
||
Line 207: | Line 207: | ||
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' |
+ | plus puisqu'� chaque appel de la routine, nous rechargeons A0 avec |
− | l'adresse du TABLEAU, donc le word |
+ | 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 |
+ | 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 |
+ | Nous avons par d�faut DEBUG INFO indiquant Extend. Cela signifie |
− | que les noms des labels vont |
+ | 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 |
+ | Surprise, les noms des labels ont disparu et sont remplac�s par |
− | des chiffres. C'est logique puisque, de toute |
+ | 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 |
+ | CHAGE. C'est un peu plus dur puisque son �tiquette n'est plus vi- |
− | sible! Pour se |
+ | 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 |
+ | 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 |
+ | 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 |
+ | 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. |
||
− | donc diff‚rente suivant les machines. Pour ma part c'est $924C6. |
||
− | J'active 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 |
+ | (pour moi) $924C6 en A0, cette adresse �tant celle pointant sur |
− | le 'A' du tableau. Ce qui m' |
+ | 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 247: | ||
MOVEA.L #$924C8,A0 pour le 'B'. |
MOVEA.L #$924C8,A0 pour le 'B'. |
||
− | Les lettres |
+ | Les lettres �tant sous forme de word dans mon tableau il faut une |
avance de 2 ! |
avance de 2 ! |
||
− | Retournons dans la |
+ | 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 |
+ | cette adresse, et notons �galement l'adresse de l'instruction sui- |
− | vante (MOVE.W (A0)+,D0). Activons la |
+ | 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 259: | ||
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 |
+ | 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 |
+ | qui reviendra � MOVEA.L #$924C8,A0 et qui me fera pointer sur le |
second word du tableau!!!!!!!! |
second word du tableau!!!!!!!! |
||
Line 284: | Line 284: | ||
RTS |
RTS |
||
− | Note: PTN_TAB ne nous sert plus, et de |
+ | 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 |
Assemblez avec NONE en DEBUG INFO, puis passez sous MONST, faites |
||
− | avancer pas |
+ | avancer pas � pas et regardez la ligne |
MOVEA.L #TABLEAU,A0 se modifier! |
MOVEA.L #TABLEAU,A0 se modifier! |
||
Line 294: | Line 294: | ||
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 |
+ | 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 |
+ | Si nous avions pr�lev� $FFFF, il aurait fallu r�initialiser notre |
ligne MOVEA.L avec |
ligne MOVEA.L avec |
||
Line 310: | Line 310: | ||
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- |
+ | 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 |
+ | (voir listing num�ro 4) |
− | Sachant que l'instruction RTS (Return from subroutine) est |
+ | Sachant que l'instruction RTS (Return from subroutine) est cod�e |
− | avec $4E75 et que l'instruction NOP (No operation) est |
+ | 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 |
+ | routine. NOP ne fait rien du tout. C'est une op�ration qui est bi- |
− | don dans le sens |
+ | don dans le sens o� rien ne change, mais cette instruction |
− | consomme un peu de temps. Elle nous servira donc pour |
+ | 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 |
+ | 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 335: | ||
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 |
+ | 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 |
+ | en d�duit que: |
ADD.W D0,D1 est converti en $D240 |
ADD.W D0,D1 est converti en $D240 |
||
Line 366: | Line 366: | ||
MOVE.L #$04410006,(A0)+ |
MOVE.L #$04410006,(A0)+ |
||
− | J'obtiendrai la |
+ | 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 380: | ||
j'obtiendrai la seconde version! |
j'obtiendrai la seconde version! |
||
− | Essayez avec le programme ci- |
+ | 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 401: | ||
END |
END |
||
− | Remarques: Il est tout |
+ | Remarques: Il est tout � fait possible d'envisager plus de 2 ver- |
− | sions d'une |
+ | sions d'une m�me partie de programme. Si les tailles de ces diff�- |
− | rentes versions |
+ | 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 |
+ | '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 |
+ | 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 414: | ||
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 l…, ils deviennent |
||
− | hyper importants, |
+ | hyper importants, �tant donn� que le listing que vous avez sous |
− | les yeux ne sera pas |
+ | les yeux ne sera pas forc�ment celui qui sera ex�cut�!!!!!!! |
</pre> |
</pre> |
||
Back to [[ASM_Tutorial]] |
Back to [[ASM_Tutorial]] |
Revision as of 15:07, 23 November 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