Initiation à lassembleur 6809
Cours n°5
Le registre DP
Nous avons déjà cité le registre DP (DirectPage) dans le cours numéro 2. Il implique une nouvelle
forme d'adressage: l'adressage direct.
Si vous définissez une zone mémoire où stocker vos registres, vous pouvez utiliser une zone dont
l'adresse de départ sera une adresse ronde de la forme $xx00 jusqu'à l'adresse $xxFF.
Le poids fort (le premier octet) de toutes ces adresses étant toujours le même,
le registre DP va vous permettre de sous-entendre ce poids fort et d'adresser
vos registres avec seulement le poids faible (le dernier octet), pour les TO:
> POKE &HA000,&H55
SETDP $A0 Déclare DP pour assemblage
DEBUT LDA #$A0 Charge valeur DP dans A > 10 A=&hA0
TFR A,DP Transfère A dans DP > 20 DP=A
LDA <$00 Charge donnée en direct > 30 A=PEEK((DP*256)+&H00)
SWI Arrêt du programme > 40 END
ORG $A000 Origine en $A000
VALEUR FCB $55 Définit une donnée en $A000
END - Fin du programme -
...et pour les MO, puisque les adresses de RAM son différentes:
> POKE &H6000,&H55
SETDP $60 Déclare DP pour assemblage
DEBUT LDA #$60 Charge valeur DP dans A > 10 A=&h60
TFR A,DP Transfère A dans DP > 20 DP=A
LDA <$00 Charge donnée en direct > 30 A=PEEK((DP*256)+&H00)
STOP Arrêt du programme > 40 END
ORG $6000 Origine en $6000
VALEUR FCB $55 Définit une donnée en $6000
END - Fin du programme -
- La directive "SETDP" va déclarer la valeur du DP pour l'assemblage des
adresses. Dans le cas du programme, elle n'est pas nécessaire.
- Les deux lignes suivantes permettent de charger DP avec la valeur voulue mais cette fois-ci à l'exécution du programme.
Cette opération s'effectue en 2 temps car il n'existe pas d'instruction
permettant d'assigner au registre DP une valeur.
- La ligne "LDA <$00" charge la valeur contenue en ($A0)00 [($60)00], $A0 ($60)
étant mis entre parenthèses puisque sous-entendu par le registre DP. Le signe
"<" force l'adressage en mode direct. Mais on aurait pu écrire
aussi "LDA <VALEUR" puisque "VALEUR" est l'étiquette
assignée à l'adresse $A000 ($6000). On aurait pu écrire de même « LDA
VALEUR » ou « LDA $A000 » (« LDA $6000 ») en se
passant du signe "<" car le fait que "SETDP" ait défini
la valeur du DP pour l'assemblage implique que tout adressage étendu rencontré
se situant de $A000 à $A0FF ($6000 à $60FF) serait automatiquement traduit en
adressage direct à l'assemblage du programme.
- Une origine ronde est définie pour initialiser un octet mémoire de valeur $55. Nous avons
donc la valeur $55 inscrite à l'adresse $A000 (POKE &HA000,&H55) [$6000
(POKE &H6000,&H55)].
Tapez "N"+RETURN puis "Y" dans la barre d'édition pour effacer le
programme précédent puis tapez, assemblez et exécutez le programme: vous
constaterez en tapant "R"+RETURN dans le moniteur que le registre A
contient bien la valeur $55 qui se trouve en $A000 ($6000).
Mais où est l'intérêt de l'adressage direct?
D'abord, sa concision. Là où l'adressage nécessiterait 3 octets à l'assemblage étendu (1
octet pour l'instruction et 2 pour l'adresse), l'adressage direct n'en utilise
que 2 (1 octet pour l'instruction et 1 octet pour le poids faible de
l'adresse). La vitesse, ensuite. Un assemblage direct, du fait de sa concision,
est plus rapidement exécuté.
Le système lui-même utilise l'adressage direct sans modération. Nous savons que la zone
mémoire qu'il réserve pour la manipulation de ses registres se trouve de $6000
à $60FF (de $2000 à $20FF sur MO), ce qui lui permet, en fixant le DP à $60 (à
$20 sur MO), d'accéder à tous ses registres en adressage direct.
Peut-être y a-t-il eu une erreur à l'assemblage: "DP Error". C'est parce que ASSEMBLER
n'a reconnu dans l'opérande <$00 que l'adresse $0000. Dans le cas où le
programmeur force lui-même l'assemblage direct, nul n'est besoin de déclarer la
valeur du DP par la directive SETDP. La nécessité de cette dernière, comme nous
l'avons déjà précisé, ne se justifie que dans le cas où les adresses sont
déclarées en mode étendu, auquel cas l'assemblage des adresses dans ce mode est
laissé à l'initiative du programme d'assemblage.
Pour un programme machine tournant sous Basic, il faudra bien veiller à restituer la valeur
initiale du DP juste avant de sortir du programme pour éviter le bogue.
Le registre CC
Le registre CC (Condition Code Register) est, comme son nom l'indique, le registre de
condition de la machine.
Lors d'une opération quelconque, le registre CC conserve automatiquement l'état de
l'opération, sans intervention du programmeur. S'il s'agit d'une opération
d'addition, par exemple, le registre CC conserve l'indication que le résultat
est égal à 0, négatif, positif, si le résultat de l'addition a dépassé le cadre
du registre, etc... Tous les branchements conditionnels dépendent de ce
registre: c'est lui qui déterminera si le branchement peut être effectué ou
non.
Flag C (Carry) [bit 0] Ce flag détermine l'état du
bit sortant lors d'une opération de décalage et sil y a eu une retenue lors
d'une opération non signée. Dans ce dernier cas, si l'opération amène le
résultat à passer les bornes 8 bits $00 (0) et $FF (255) ou 16 bits $0000 (0)
et $FFFF (65535), cet indicateur est mis à 1.
Flag V (OverFlow) [bit 1] Ce flag détermine notamment
si la retenue courante (flag C) est différente de celle de lopération
précédente. Cet indicateur est alors mis à 1.
Flag Z (Zero) [bit 2] Ce flag détermine si l'opération
effectuée donne un résultat égal à 0 ou si deux valeurs sont égales lors d'une
comparaison. Dans le cas de l'égalité, il est mis à 1. Dans le cas de
l'inégalité, il est mis à 0.
Flag N (Negative) [bit 3] Ce flag détermine si
l'opération effectuée donne un résultat négatif ou positif. Dans le cadre des 8
bits, les nombres positifs vont de $00 à $7F et les nombres négatifs vont de
$80 à $FF. Dans le cadre des 16 bits, les nombres positifs vont de $0000 à
$7FFF et les nombres négatifs de $8000 à $FFFF.
Flag I (IRQ interrupt mask) [bit 4] Ce flag est
activé ou désactivé par le programmeur à l'aide des instructions ORCC ou ANDCC.
S'il est mis à 1, l'interruption IRQ est "gelée", c'est à dire que le
système est interdit d'y faire appel. S'il est mis à 0, l'interruption IRQ est
"dégelée".
Flag H (Half carry) [bit 5] Ce flag sert pour
l'ajustement décimal introduit par l'instruction DAA. S'il est à 1 (pour les
valeurs de quartet $A, $B, $C, $D, $E et $F), DAA ajoute 6 au résultat pour ajuster
le registre en décimal.
Flag F (FIRQ interrupt mask) [bit 6] Ce flag est
activé ou désactivé par le programmeur à l'aide des instructions ORCC ou ANDCC.
S'il est mis à 1, l'interruption FIRQ est "gelée", c'est à dire que
le système est interdit d'y faire appel. S'il est mis à 0, l'interruption FIRQ
est "dégelée".
Flag E (Entire flag) [bit 7] Ce flag est réservé par
le système pour déterminer la taille d'empilement en entrée et en sortie des
interruptions (conclues par l'instruction RTI).
|