Je suis en train de me faire un set de macro-instructions pour me faciliter l'écriture d'algorithmes complexes en ASM. J'en dirais plus à ce sujet plus tard, mais en travaillant dessus je suis tombé sur une difficulté.
La problématique posée est celle ci: écrire une macro "JP label" qui, en fonction du label passe automatiquement entre un BRA et un JMP. Je me suis dit que c'était pas bien compliqué d'écrire une macro qui test la distance entre *+2 et lbl et si c'est entre -128 et 127 fait un BRA label et JMP label sinon. Ca donne quelque chose comme ceci:
Code:
JP MACRO
echo saut en $\0
IFEQ (\0-*-2)&$FF80
bra \0 ; branchements positifs
ELSE
IFEQ (*+1-\0)&$FF80
bra \0 ; branchements negatifs
ELSE
jmp \0
ENDC
ENDC
ENDM
Bon.
Je teste quelques cas:
Code:
JP L1
L0
RMB 126,0
L1
JP L0
echo L0=$L0
echo L1=$L1
Et là surprise, c6809 0.83 me donne
Code:
159 IFEQ (L1-*-2)&$FF80
160 3 9000 20 7F bra L1 ; branchements positi>>
161 ELSE
162 IFEQ (*+1-L1)&$FF80
163 bra L1 ; branchements negati>>
164 ELSE
165 jmp L1
166 ENDC
167 ENDC
171 9002 L0
172 9002 RMB 126,0
173 9080 L1
159 IFEQ (L0-*-2)&$FF80
160 bra L0 ; branchements positi>>
161 ELSE
162 IFEQ (*+1-L0)&$FF80
163 3 9080 20 81 bra L0 ; branchements negati>>
164 ELSE
165 jmp L0
166 ENDC
167 ENDC
On voit que les offsets des BRA sont faux. Pour aller de $9002 à $9080 c'est un +126 (taille du RMB) qu'il faudrait et on obtient un +127. A l'inverse pour aller dans l'autre sens c'est -128 qu'il faut et on obtient -127. Bref les sauts sont 1 octet trop long ou trop court. C'est confirmé avec ce qu'on voit sur la console:
Code:
tools/c6809.exe -c -bh -am -oOP fpu.ass `echo fpu.BIN|tr a-z A-Z`
Macro Pass
Pass1
Pass2
saut en $9081
saut en $9003
L0=$9003
L1=$9081
000000 Total Errors
Et oui, pour l'assembleur L0 et L1 ne correspondent pas à ce qu'on voit dans le fichier CODE.LST qui est généré et qui contient l'asm vraiment produit.
D'où est-ce que cela peut provenir ? J'imagine que cela vient du fait que la macro est de taille variable (particularité de cette macro). Si le IF est vrai, alors il y a 2 octets de code (ce qu'on voit dans le code.lst), sinon 3 (ce qu'on voit dans la console). Ca doit pouvoir expliquer le décalage de 1 si le calcul des adresses interpréte mal le IF.
Ca m'ennuie parce que je commençais à utiliser cette macro un peu partout et que le décalage introduit fait complètement bugger les trucs en sautant en plein milieu d'une instruction.