Question débutant 6809
Modérateurs : Papy.G, fneck, Carl
- z80¯\_(ツ)_/¯
- Messages : 77
- Inscription : 06 oct. 2020 13:15
- Localisation : Bourgogne
Question débutant 6809
Bonjour,
Je voudrais savoir s'il est possible en assembleur 6809 de sauvegarder le PC dans la pile mais en lui ajoutant un nombre de façon à reprendre légèrement plus loin après un RTS dans une sous routine après un branchement.
Je ne sais pas si je suis clair mais en gros, un truc du genre :
PSHS PC + 2
CMPD #0
BGE UPDATE_P1 * Branchement routine (et je voudrais qu'un RTS dans la sous routine me rebranche à la ligne juste en dessous)
REPRISE APRES RTS (dans la sous routine)
Je voudrais savoir s'il est possible en assembleur 6809 de sauvegarder le PC dans la pile mais en lui ajoutant un nombre de façon à reprendre légèrement plus loin après un RTS dans une sous routine après un branchement.
Je ne sais pas si je suis clair mais en gros, un truc du genre :
PSHS PC + 2
CMPD #0
BGE UPDATE_P1 * Branchement routine (et je voudrais qu'un RTS dans la sous routine me rebranche à la ligne juste en dessous)
REPRISE APRES RTS (dans la sous routine)
Re: Question débutant 6809
Je pense que ce problème n'est pas spécifique au 6809. Revenir d'une sous-routine avec un RET (RTS) alors qu'elle n'a pas été appelée par un CALL mais uniquement un saut donc adresse de retour non empilée.
Je ne pense pas qu'un seul processeur 8-bit permette de faire des opérations d'addition sur une instruction PUSH. A mon avis il faut charger l'adresse de retour indiquée par un label sur l'instruction dans un registre puis faire un PUSH de ce registre avant le saut.
J'ai aussi vu des routines sur CPC où la valeur de retour était PUSHée juste avant le RET dans la sous routine...
Dès lors qu'on sait que le RET va dépiler une valeur pour la mettre dans PC et continuer l'exécution on peut bricoler ce qu'on veut tant qu'on retombe toujours sur nos pattes.
On a beaucoup décrié le Basic comme étant le langage des programmes spaghetti mais je crois qu'on fait bien pire en assembleur.
EDIT il ne faut pas sous-estimer la puissance des labels/étiquettes car c'est l'assembleur qui va faire l'énorme travail de calculer l'adresse au final et à chaque modif du programme le calcul est actualisé.
Je ne pense pas qu'un seul processeur 8-bit permette de faire des opérations d'addition sur une instruction PUSH. A mon avis il faut charger l'adresse de retour indiquée par un label sur l'instruction dans un registre puis faire un PUSH de ce registre avant le saut.
J'ai aussi vu des routines sur CPC où la valeur de retour était PUSHée juste avant le RET dans la sous routine...
Dès lors qu'on sait que le RET va dépiler une valeur pour la mettre dans PC et continuer l'exécution on peut bricoler ce qu'on veut tant qu'on retombe toujours sur nos pattes.
On a beaucoup décrié le Basic comme étant le langage des programmes spaghetti mais je crois qu'on fait bien pire en assembleur.
EDIT il ne faut pas sous-estimer la puissance des labels/étiquettes car c'est l'assembleur qui va faire l'énorme travail de calculer l'adresse au final et à chaque modif du programme le calcul est actualisé.
-
- Messages : 2336
- Inscription : 06 avr. 2009 12:07
Re: Question débutant 6809
Mais pourquoi pas juste un BLO ou BMI skip_jump suivi d'un jsr ?
au moment ou tu fais ton "PSHS PC+2" le PC est déjà apres le PSHS, donc le but c'est de revenir au milieu du CMPD ? Pas sur de comprendre.
le JSR n'est rien d'autre qu'un PSHS PC suivi d'un JMP, donc pour sauter ailleurs, il suffit de faire un STX #adr, PSHS X, JMP routine.
Code : Tout sélectionner
CMPD #0
BLO skip_jump
jsr routine
skip_jump:
REPRISE APRES RTS
le JSR n'est rien d'autre qu'un PSHS PC suivi d'un JMP, donc pour sauter ailleurs, il suffit de faire un STX #adr, PSHS X, JMP routine.
Re: Question débutant 6809
On ne peut pas empiler PC augmenté de 2 avec une seule instruction.
Il faut transférer PC dans un autre registre 16 bits, par exemple X, ajouter 2 à X et empiler X.
Il faut transférer PC dans un autre registre 16 bits, par exemple X, ajouter 2 à X et empiler X.
Daniel
L'obstacle augmente mon ardeur.
L'obstacle augmente mon ardeur.
Re: Question débutant 6809
Ce que tu veux faire, c'est l'équivalent en Z80 :
, non ?
C'est à dire on ne saute à UPDATE_P1 que si A >= 0 ? si c'est le cas, je pense que la réponse de Fool-Duplex est la plus appropriée. Je ne crois pas qu'en passant par un PSHS, on y gagne en nombre de cycles et d'octets et de registre consommé.
Pour un cas plus général avec un PC + n, une fois de plus il peut y avoir une solution mieux adaptée. Le tout est de ne pas se laisser enfermé par cette idée de vouloir faire comme ça comme c'est très souvent le cas.
Code : Tout sélectionner
OR A
CALL NS, UPDATE_P1
...
C'est à dire on ne saute à UPDATE_P1 que si A >= 0 ? si c'est le cas, je pense que la réponse de Fool-Duplex est la plus appropriée. Je ne crois pas qu'en passant par un PSHS, on y gagne en nombre de cycles et d'octets et de registre consommé.
Pour un cas plus général avec un PC + n, une fois de plus il peut y avoir une solution mieux adaptée. Le tout est de ne pas se laisser enfermé par cette idée de vouloir faire comme ça comme c'est très souvent le cas.
-
- Messages : 7964
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: Question débutant 6809
Hum
Je pense que tu souhaites un truc à la Push the Effective Adresse du 68000, grand frère du 6809. Hélas cela n'existe pas sur cette génération. Cependant il y a plein de façon de le faire quand même en trashant des registres:ou encoreA noter que tu peux même te passer du PSHS X/RTS dans la 1ere option en faisant un "JMP ,X" au lieu du RTS.
Mais je pense que dans ton cas la solution de fool est la mieux: retourne avec à BRA/JMP à l'adresse "PC+2" que tu voulais. C'est plus dans l'esprit 6809.
Code : Tout sélectionner
PSHS PC + nnnn
Code : Tout sélectionner
PEA nnnn(PC)
Code : Tout sélectionner
LEAX LABEL_REPRISE,PCR ; ou LDX #LABEL_REPRISE si on ne veut pas faire de code relogeable.
PSHS X ; on peut remplacer X par D si on fait du LDr au lieu de LEAr (LEAD n'existe pas)
Code : Tout sélectionner
PSHS PC
LDD #N (à ajuster en fonction des instruction qui suivent pour bien empiler LABEL_REPRISE)
ADDD ,S
STD ,S
Mais je pense que dans ton cas la solution de fool est la mieux: retourne avec à BRA/JMP à l'adresse "PC+2" que tu voulais. C'est plus dans l'esprit 6809.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
- z80¯\_(ツ)_/¯
- Messages : 77
- Inscription : 06 oct. 2020 13:15
- Localisation : Bourgogne
Re: Question débutant 6809
Merci pour toutes ces informations.
Je vais tester tout ça.
Je vais tester tout ça.
- z80¯\_(ツ)_/¯
- Messages : 77
- Inscription : 06 oct. 2020 13:15
- Localisation : Bourgogne
Re: Question débutant 6809
J'ai testé :
Ca fonctionne.
Pouvez-vous me confirmer que le 10 vient du fait qu'on doit passer 4 instructions (donc 8 octets) et se positionner sur la cinquième (donc 10 octets) par rapport au PSHS PC ?
Code : Tout sélectionner
PSHS PC * PC dans la pile S
LDD #10 * 10 dans D
ADDD ,S * ajoute S dans D
STD ,S * sauvegarde D dans S
JMP DRAWXY * JMP avec RTS dans la sous routine
NOP * Le RTS de la sous routine reprend bien ici
Pouvez-vous me confirmer que le 10 vient du fait qu'on doit passer 4 instructions (donc 8 octets) et se positionner sur la cinquième (donc 10 octets) par rapport au PSHS PC ?
-
- Messages : 7964
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: Question débutant 6809
Non pas "donc". Les instructions ne sont pas de taille unique. Un LDD #nnnn prends 3 octets, un "ADD ,S" en prends 2, un NOP un seul. Fais une execution pas à pas dans l'émulateur pour voir si le calcule te donne bien l'adresse du NOP. C'est le plus simple. (sinon si on préfère le calcul théorique à l'expérimentation sous émulateur on a: "LDD #10"=3, "ADD ,S"=2, "STD ,S"=2, "JMP PLOTXY"=3. TOTAL=10)z80¯\_(ツ)_/¯ a écrit : ↑05 août 2021 13:18 Pouvez-vous me confirmer que le 10 vient du fait qu'on doit passer 4 instructions (donc 8 octets)
Mais plus simple encore est d'utiliser un LABEL. L'assembleur va faire le calcul pour toi:
Code : Tout sélectionner
PSHS PC
LDD #REPRISE-* (* = La valeur de PC qui vient juste d'être empilée)
ADDD ,S
STD ,S
JMP DRAWXY
.. blabla ..
REPRISE
NOP
Code : Tout sélectionner
LDD #REPRISE * ou / LEAX REPRISE,PCR
PSHS D * \ PSHS X
JMP DRAWXY * JMP avec RTS dans la sous routine
REPRISE
NOP * Le RTS de la sous routine reprend bien ici
Code : Tout sélectionner
JSR DRAWXY * Empile le PC sur l'instruction (suivante) et saute (JMP) dans la sous routine
NOP * Le RTS de la sous routine reprend bien ici
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
-
- Messages : 2336
- Inscription : 06 avr. 2009 12:07
Re: Question débutant 6809
Et donc, quel est l'intérêt de se compliquer ainsi la vie ?
- z80¯\_(ツ)_/¯
- Messages : 77
- Inscription : 06 oct. 2020 13:15
- Localisation : Bourgogne
Re: Question débutant 6809
C'est très intéressant