La Place des Développeurs Question assembleur
Je tente d'analyser (et de faire partager par la suite le fruit de ces analyses) une portion de programme en assembleur.
Ce code fait clignoter un texte, et fait passer à une autre étape en poussant l'un des boutons feu.
Je pense avoir saisi le principe mais quelque chose m'échappe, je voudrais avoir quelques explications sur la portion de code suivante (syntaxe asmsx). En rouge, ce que je comprends (désolé pour la présentation; qui est toute caca... ) :
xor a mise à 0 de l'accumulateur
@@MENU: étiquette de sous-programme
push af on empile l'accumulateur
; Sync with V-blank interruption
halt pause
; Check buttons
; Space bar:
xor a mise à 0 de l'accumulateur
call GTTRIG appel de la routine BIOS qui vérifie l'appui sur le bouton feu suivant la valeur de l'accumulateur (0 : clavier, 1 : joystick 1, 2 : joystick 2) : renvoie 0 si rien, 255 ou ffh si le bouton est poussé
or a test de la valeur renvoyée par GTTRIG : on applique un "or" à l'accumulateur pour modifier le flag z du registre F : z=1 si a=0, z=0 si a=ffh, donc nz=1 si z=0 et inversement
jr nz,@@READY saut au sous-programme READY si nz=1 (donc si la barre d'espace est poussée)
; Joystick 1 idem précédent, pour le joystick 1
ld a,1
call GTTRIG
or a
jr nz,@@READY
; Joystick 2 idem précédent, pour le joystick 2
ld a,2
call GTTRIG
or a
jr nz,@@READY
pop af on dépile l'accumulateur : il vaut alors 0 (valeur lors de l'empilement)
; Check if blink is needed
inc a incrémentation de l'accumulateur : a vaut 1
ld b,a on affecte la valeur de a dans le registre b : b vaut 1
and 0fh on compare la valeur de a avec 0fh : le résultat de l'opération est stockée dans l'accumulateur, le flag z du registre f est modifié en fonction de l'opération : si a=0, z=1, nz=0 et inversement. Au premier passage, a=1
ld a,b a reprend la valeur qu'il avait précédemment
jr nz,@@MENU a=1 au premier passage : on retourne à @@MENU. La suite du programme lorsque a aura comme valeur 10h
; Draws or erases the text
push af on empile a : valeur théorique du premier passage : 10h
and 10h on stocke dans l'accumulateur le résultat du ET logique, ici pour le premier cas 10h
jr z,@@ERASE si le flag Z est mis à 1 (donc si le résultat de l'opération précédente est 0), on saute à @@ERASE, on continue sinon, ce qui est le cas pour 10h
; Draws text PUSH BUTTON écriture du texte
ld hl,TXT_BUTTON
ld de,NAMTBL+32*15+9
ld bc,14
call LDIRVM
pop af on dépile a
jr @@MENU saut à @@MENU
; Erases text effacement du texte
@@ERASE:
ld hl,NAMTBL+32*15+9
ld bc,14
xor a
call FILVRM
pop af on dépile a
jr @@MENU saut à @@MENU
; Return to main menu
@@READY:
suite du programme
Ce que je ne saisis pas, c'est que la valeur de l'accumulateur ne cesse d'être incrémentée ! Si j'ai bien suivi, toutes les 16 valeurs, le texte apparaît et disparaît successivement. Comment se fait-il que le programme ne plante pas après 16 clignotements ? La valeur de A dépasserait alors 256 !!
Je ne sais pas si je suis très clair dans mes explications et dans ma question...
Ce code fait clignoter un texte, et fait passer à une autre étape en poussant l'un des boutons feu.
Je pense avoir saisi le principe mais quelque chose m'échappe, je voudrais avoir quelques explications sur la portion de code suivante (syntaxe asmsx). En rouge, ce que je comprends (désolé pour la présentation; qui est toute caca... ) :
xor a mise à 0 de l'accumulateur
@@MENU: étiquette de sous-programme
push af on empile l'accumulateur
; Sync with V-blank interruption
halt pause
; Check buttons
; Space bar:
xor a mise à 0 de l'accumulateur
call GTTRIG appel de la routine BIOS qui vérifie l'appui sur le bouton feu suivant la valeur de l'accumulateur (0 : clavier, 1 : joystick 1, 2 : joystick 2) : renvoie 0 si rien, 255 ou ffh si le bouton est poussé
or a test de la valeur renvoyée par GTTRIG : on applique un "or" à l'accumulateur pour modifier le flag z du registre F : z=1 si a=0, z=0 si a=ffh, donc nz=1 si z=0 et inversement
jr nz,@@READY saut au sous-programme READY si nz=1 (donc si la barre d'espace est poussée)
; Joystick 1 idem précédent, pour le joystick 1
ld a,1
call GTTRIG
or a
jr nz,@@READY
; Joystick 2 idem précédent, pour le joystick 2
ld a,2
call GTTRIG
or a
jr nz,@@READY
pop af on dépile l'accumulateur : il vaut alors 0 (valeur lors de l'empilement)
; Check if blink is needed
inc a incrémentation de l'accumulateur : a vaut 1
ld b,a on affecte la valeur de a dans le registre b : b vaut 1
and 0fh on compare la valeur de a avec 0fh : le résultat de l'opération est stockée dans l'accumulateur, le flag z du registre f est modifié en fonction de l'opération : si a=0, z=1, nz=0 et inversement. Au premier passage, a=1
ld a,b a reprend la valeur qu'il avait précédemment
jr nz,@@MENU a=1 au premier passage : on retourne à @@MENU. La suite du programme lorsque a aura comme valeur 10h
; Draws or erases the text
push af on empile a : valeur théorique du premier passage : 10h
and 10h on stocke dans l'accumulateur le résultat du ET logique, ici pour le premier cas 10h
jr z,@@ERASE si le flag Z est mis à 1 (donc si le résultat de l'opération précédente est 0), on saute à @@ERASE, on continue sinon, ce qui est le cas pour 10h
; Draws text PUSH BUTTON écriture du texte
ld hl,TXT_BUTTON
ld de,NAMTBL+32*15+9
ld bc,14
call LDIRVM
pop af on dépile a
jr @@MENU saut à @@MENU
; Erases text effacement du texte
@@ERASE:
ld hl,NAMTBL+32*15+9
ld bc,14
xor a
call FILVRM
pop af on dépile a
jr @@MENU saut à @@MENU
; Return to main menu
@@READY:
suite du programme
Ce que je ne saisis pas, c'est que la valeur de l'accumulateur ne cesse d'être incrémentée ! Si j'ai bien suivi, toutes les 16 valeurs, le texte apparaît et disparaît successivement. Comment se fait-il que le programme ne plante pas après 16 clignotements ? La valeur de A dépasserait alors 256 !!
Je ne sais pas si je suis très clair dans mes explications et dans ma question...
MSX un jour, MSX toujours !
je n'aime pas du tout la façon dont cet assembleur écrit ses labels on croirait du C
pour débugger as tu essayé de le lancer dans Ru-MSX
c'est le seul programme a ma connaissance a pouvoir tracer sur écran ou dans un fichier texte
sinon as tu le programme en entier et sous forme de fichier.com pour le tester
pour débugger as tu essayé de le lancer dans Ru-MSX
c'est le seul programme a ma connaissance a pouvoir tracer sur écran ou dans un fichier texte
sinon as tu le programme en entier et sous forme de fichier.com pour le tester
Euh, je n'ai pas trop le tempsde décrypter le programme, mais pour ta réflexion de fin, l'accumulateur boucle!
Ne jamais oublier que 255 est aussi -1 et que si tu lui ajoute1 tu obtiens 0 et non 256 et c'est reparti pour un tour vers l'infini et au delàààà
Il y a juste le flag qui doit passer à 1 si mes souvenirs sont bons (je dis ça de tête et je suis loin d'être un expert).
Ne jamais oublier que 255 est aussi -1 et que si tu lui ajoute1 tu obtiens 0 et non 256 et c'est reparti pour un tour vers l'infini et au delàààà
Il y a juste le flag qui doit passer à 1 si mes souvenirs sont bons (je dis ça de tête et je suis loin d'être un expert).
Le MSXien le plus à l'ouest ... ou presque
J'imagine que tu parles du flag parité/dépassement ? Je suis mitigé en ce qui concerne le carry sur ce coup-là, j'arrive donc plus ou moins à la même conclusion...
Pour Jipe : le programme ne bugge pas, il marche au poil, c'est juste que je me demande comment il fait pour ne pas planter ! Là je ne pars que sur des suppositions qui me paraissent pas trop mal, mais qui restent des suppositions ! Si cependant tu veux y regarder de plus près, tu as le listing complet dans le pack asmsx de la rubrique téléchargement (pong.asm).
C'est en testant manuellement que je vois que ça boucle en permanence, l'explication de Pascal me paraît de plus en plus cohérente du coup !
Pour Jipe : le programme ne bugge pas, il marche au poil, c'est juste que je me demande comment il fait pour ne pas planter ! Là je ne pars que sur des suppositions qui me paraissent pas trop mal, mais qui restent des suppositions ! Si cependant tu veux y regarder de plus près, tu as le listing complet dans le pack asmsx de la rubrique téléchargement (pong.asm).
C'est en testant manuellement que je vois que ça boucle en permanence, l'explication de Pascal me paraît de plus en plus cohérente du coup !
MSX un jour, MSX toujours !
j'ai lu trop vite hier soir
mais pour Ru-Msx ça reste un super outil pour tracer un programme
mode d'emploi succint
Debug Setting
Trace : tracing on
Output : file (append) pour avoir le résultat dans un fichier
Output : Debug Windows pour avoir le résultat dans une fenêtre visible par Debug : Debug Windows
les options du Verbose sont aussi utiles ex: voir les accés au VDP a la mémoire ou au disque
mais pour Ru-Msx ça reste un super outil pour tracer un programme
mode d'emploi succint
Debug Setting
Trace : tracing on
Output : file (append) pour avoir le résultat dans un fichier
Output : Debug Windows pour avoir le résultat dans une fenêtre visible par Debug : Debug Windows
les options du Verbose sont aussi utiles ex: voir les accés au VDP a la mémoire ou au disque
Walter
Membre non connecté
Conseiller Municipal
Ben oui les gars. C'est pour cela aussi, que cela me fait rire les critiques de jeux dans les magasines.
Elles sont faites par des personnes, qui ne savent même pas faire PRINT "Bonjour" en Basic.
Pour ceux qui n'exploreraient pas bien notre site, consultez CE LIEN pour infos.
Elles sont faites par des personnes, qui ne savent même pas faire PRINT "Bonjour" en Basic.
Pour ceux qui n'exploreraient pas bien notre site, consultez CE LIEN pour infos.
C'est sûr que vu comme ça, ça paraît compliqué, mais avec un minimum de connaissances fournies dans les bouquins, on peut arriver à comprendre (et apprendre) ! Si moi j'y arrive, tout le monde peut le faire !
MSX un jour, MSX toujours !
L'explication de Osaure est tout à fait bonne.
Le registre A est sur un octet (donc sur 8 bits).
Il peut donc représenter :
- un nombre de 0 à 255,
- un nombre de -127 à 127,
- un caractère (grâce au codage ASCII)
La signification de cet octet va dépendre du programmeur (ou du contexte), mais pas de la machine
Le plus simple, on va considérer que le registre A contient 255, donc les 8 éléments binaires sont à la valeur 1. Etudions l'ajout de la valeur 1 à ce moment précis.
Reg A : 1111 1111
+ 1
Le calcul va générer ce résultat 1 0000 0000 (Rappel : en binaire 1+1 = 0 et une retenue de 1). Le résultat va être transmis au registre A. Mais, comme le registre A ne peut contenir que 8 éléments binaires, il va prendre la valeur 0000 0000 soit 0. Edité par KN2000 Le 09/06/2010 à 19h35
Le registre A est sur un octet (donc sur 8 bits).
Il peut donc représenter :
- un nombre de 0 à 255,
- un nombre de -127 à 127,
- un caractère (grâce au codage ASCII)
La signification de cet octet va dépendre du programmeur (ou du contexte), mais pas de la machine
Le plus simple, on va considérer que le registre A contient 255, donc les 8 éléments binaires sont à la valeur 1. Etudions l'ajout de la valeur 1 à ce moment précis.
Reg A : 1111 1111
+ 1
Le calcul va générer ce résultat 1 0000 0000 (Rappel : en binaire 1+1 = 0 et une retenue de 1). Le résultat va être transmis au registre A. Mais, comme le registre A ne peut contenir que 8 éléments binaires, il va prendre la valeur 0000 0000 soit 0. Edité par KN2000 Le 09/06/2010 à 19h35
Nous sommes en 2010 aps JC, toute la Gaule est envahie. Ah ben non, apparement, un village résiste encore aux envahisseurs Personalcomputerum et autres Consoledessalum. Bienvenue dans l'antre du emessix !
Lorsque le registre A vaut 255 et qu'il est incrémenté, il revient à zéro.
Après un INC A, les flags sont affectés comme suit :
S est à 1 si le résultat est négatif (en entier signé), sinon il est à zéro
Z est à 1 si le résultat est zéro, sinon il est à zéro
P/V est mis à 1 si le registre valait $7F avant l'opération, sinon il est à zéro
N est mis à zéro
C n'est pas modifié
PS : J'arrive un peu après la bataille
EDIT : C'est encore pire que ce que je pensais
Je croyais que le sujet avait été démarré en décembre dernier, mais c'est en décembre 2009
Après un INC A, les flags sont affectés comme suit :
S est à 1 si le résultat est négatif (en entier signé), sinon il est à zéro
Z est à 1 si le résultat est zéro, sinon il est à zéro
P/V est mis à 1 si le registre valait $7F avant l'opération, sinon il est à zéro
N est mis à zéro
C n'est pas modifié
PS : J'arrive un peu après la bataille
EDIT : C'est encore pire que ce que je pensais
Je croyais que le sujet avait été démarré en décembre dernier, mais c'est en décembre 2009
MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie