Exercices de Programmation Corrigés sur le Microprocesseur 6809
Recommandés
Vous allez réellement progresser sur le microprocesseur 6809 en pratiquant. Cette page vous propose une série d’exercices en assembleur 6809 classés par niveau, avec des corrigés expliqués qui vous guident pas à pas : registres, modes d’adressage, accès mémoire, boucles, tests, sous-programmes, et premières bases des interruptions. L’objectif est clair : vous entraîner comme en TP, gagner en réflexes, écrire des routines propres, puis repartir avec des solutions réutilisables et faciles à adapter à vos propres cas.
Microprocesseur 6809 : exercices corrigés en assembleur pour progresser pas à pas
Le microprocesseur Motorola 6809 est un processeur 8 bits très puissant pour son époque, offrant des instructions avancées, notamment la prise en charge d’adressage indirect et une architecture optimisée pour la programmation en langage assembleur. Ce guide présente des exercices corrigés pour comprendre la programmation de base du microprocesseur 6809.
Nous allons passer en revue la manipulation des registres, les instructions de branchement, les interruptions et la gestion des entrées/sorties (E/S).
Comment fonctionne un assembleur
Vous écrivez du code lisible. L’assembleur transforme vos instructions en opcodes exécutables par le microprocesseur.
; Exemple 6809 ORG $1000 LDA #$2A STA $2000 BRA LOOP LOOP: NOP BRA LOOP
- Analyse le texte (syntaxe)
- Résout les labels (adresses)
- Traduit en opcodes
- Produit binaire + listing + symboles
Adresse Données (hex)
$1000 86 2A B7 20 00 20 FB 12 20 FD
Idée : le CPU lit ces octets, met à jour PC/registre/mémoire,
et exécute instruction par instruction.
✅ En résumé : l’assembleur joue le rôle de traducteur entre votre code lisible et le binaire exécuté par le microprocesseur.
Exercice 1 : Addition de deux nombres stockés en mémoire
Contexte :
Écrire un programme en assembleur pour le microprocesseur 6809 qui additionne deux nombres 8 bits stockés en mémoire aux adresses $1000 et $1001, puis place le résultat à l’adresse $1002.
Correction :
ORG $1000 ; Début du programme
LDA $1000 ; Charger le premier nombre depuis l'adresse $1000 dans A
ADDA $1001 ; Ajouter le contenu de l'adresse $1001 au registre A
STA $1002 ; Stocker le résultat à l'adresse $1002
SWI ; Arrêt du programmeExplication :
- ORG $1000 : Définit l’origine de l’assemblage à l’adresse mémoire
$1000. - LDA $1000 : Charge la valeur stockée à l’adresse
$1000dans le registre A. - ADDA $1001 : Ajoute la valeur stockée à l’adresse
$1001à la valeur du registre A. - STA $1002 : Stocke le résultat de l’addition dans la mémoire à l’adresse
$1002. - SWI : Interruption logicielle pour indiquer la fin du programme.
Exercice 2 : Comparaison de deux nombres et branchement
Contexte :
Écrire un programme qui compare deux nombres stockés à $2000 et $2001. Si le premier nombre est plus grand, le programme stocke 1 à l’adresse $2002. Si le deuxième est plus grand ou égal, il stocke 0.
Correction :
ORG $2000 ; Début du programme
LDA $2000 ; Charger le premier nombre dans A
CMPA $2001 ; Comparer avec le nombre à l'adresse $2001
BHI STORE_ONE ; Si A est plus grand, sauter à STORE_ONE
LDA #0 ; Sinon, charger 0 dans A
BRA STORE_RESULT ; Aller à la partie où on stocke le résultat
STORE_ONE:
LDA #1 ; Charger 1 dans A
STORE_RESULT:
STA $2002 ; Stocker le résultat à l'adresse $2002
SWI ; Fin du programmeExplication :
- CMPA $2001 : Compare le contenu du registre A avec la valeur de l’adresse
$2001. - BHI STORE_ONE : Branche si le contenu du registre A est supérieur (non signé) à la valeur de l’adresse
$2001. - BRA STORE_RESULT : Saute directement à l’instruction qui stocke le résultat.
- STA $2002 : Stocke le résultat final (
1ou0) dans la mémoire.
Exercice 3 : Boucle de comptage avec affichage d’une séquence
Contexte :
Écrire un programme qui compte de 1 à 10 et affiche chaque nombre dans la mémoire à l’adresse $3000. Le programme utilise une boucle pour incrémenter un compteur et s’arrête lorsque la valeur 10 est atteinte.
Correction :
ORG $3000 ; Début du programme
LDX #1 ; Initialiser X à 1 (début du comptage)
LOOP:
STX $3000 ; Stocker la valeur de X dans $3000
INX ; Incrémenter X
CPX #11 ; Comparer X avec 11 (fin de la boucle)
BNE LOOP ; Si X n'est pas égal à 11, continuer la boucle
SWI ; Fin du programmeExplication :
- LDA #1 : Initialiser le registre X à 1, qui servira de compteur.
- STX $3000 : Stocke la valeur du registre X à l’adresse
$3000. - INX : Incrémente la valeur du registre X.
- CPX #11 : Compare la valeur de X avec 11 pour déterminer la fin de la boucle.
- BNE LOOP : Si X n’est pas égal à 11, le programme retourne au début de la boucle.
Exercice 4 : Lecture d’un bouton avec le PIA et allumage d’un voyant
Contexte :
Un bouton est connecté au port A du PIA (Peripheral Interface Adapter) à l’adresse $4000. Un voyant est connecté au port B à l’adresse $4001. Si le bouton est enfoncé (valeur logique 1), le programme doit allumer le voyant en écrivant 1 à l’adresse $4001. Si le bouton est relâché (valeur logique 0), le programme doit éteindre le voyant.
Correction :
ORG $4000 ; Début du programme
LDA $4000 ; Lire l'état du bouton sur le port A du PIA
CMPA #1 ; Comparer l'état du bouton avec 1 (bouton enfoncé)
BEQ TURN_ON ; Si égal, aller à TURN_ON pour allumer le voyant
LDA #0 ; Sinon, éteindre le voyant
STA $4001 ; Écrire 0 au port B pour éteindre le voyant
BRA END ; Aller à la fin du programme
TURN_ON:
LDA #1 ; Charger 1 pour allumer le voyant
STA $4001 ; Écrire 1 au port B pour allumer le voyant
END:
SWI ; Fin du programmeExplication :
- LDA $4000 : Lire l’état du bouton connecté au port A du PIA.
- CMPA #1 : Comparer avec
1pour vérifier si le bouton est enfoncé. - BEQ TURN_ON : Si le bouton est enfoncé, le programme saute à l’instruction TURN_ON pour allumer le voyant.
- LDA #0 : Sinon, charger
0dans le registre A pour éteindre le voyant.
Exercice 5 : Gestion d’une interruption
Contexte :
Programmer une interruption qui se déclenche lorsqu’un bouton connecté au port A du PIA est pressé. Lorsque l’interruption se produit, un voyant connecté au port B du PIA doit s’allumer.
Correction :
ORG $5000 ; Début du programme principal
CLI ; Activer les interruptions
LDX #ISR ; Charger l'adresse de la routine d'interruption
STX $FFF2 ; Stocker l'adresse de l'interruption à l'adresse du vecteur d'IRQ
SWI ; Fin du programme principal
ISR:
LDA $4000 ; Lire l'état du bouton
CMPA #1 ; Comparer avec 1 (si le bouton est enfoncé)
BEQ TURN_ON_ISR ; Si égal, allumer le voyant
BRA END_ISR ; Sinon, sortir
TURN_ON_ISR:
LDA #1 ; Charger 1 pour allumer le voyant
STA $4001 ; Écrire 1 au port B pour allumer le voyant
END_ISR:
RTI ; Retour de l'interruptionExplication :
- CLI : Activer les interruptions.
- STX $FFF2 : Stocker l’adresse de la routine d’interruption (ISR) dans le vecteur d’interruption IRQ.
- ISR : La routine d’interruption est déclenchée lorsque le bouton est pressé. Si le bouton est enfoncé, le voyant est allumé.
Le microprocesseur 6809 offre une architecture puissante pour la programmation en assembleur, particulièrement utile dans les systèmes embarqués. Les exercices présentés permettent de se familiariser avec les bases de la manipulation des registres, les instructions de branchement conditionnel, les boucles, et l’interfaçage avec des périphériques via le PIA. Ces concepts sont fondamentaux pour comprendre et maîtriser la programmation à bas niveau sur des microprocesseurs anciens mais encore utilisés dans certaines applications critiques.
💡
La programmation sur le microprocesseur 6809 présente plusieurs avantages qui le distinguent des autres processeurs 8 bits de son époque. Bien que développé dans les années 1970-1980, le 6809 était en avance sur son temps avec plusieurs caractéristiques innovantes qui facilitaient la programmation en langage assembleur et amélioraient les performances du système. Voici quelques-uns des principaux avantages de la programmation sur le 6809 :
1. Jeu d’instructions avancé
Le 6809 dispose d’un jeu d’instructions plus avancé et plus orthogonal par rapport à d’autres processeurs 8 bits comme le 6502 ou le Z80. Cela signifie que la plupart des instructions peuvent s’appliquer à un plus grand nombre de modes d’adressage et de registres. Voici quelques avantages spécifiques liés au jeu d’instructions du 6809 :
- Instructions multioctets : Le 6809 permet des opérations sur des entiers 16 bits en plus des entiers 8 bits, ce qui est particulièrement utile pour manipuler de plus grandes quantités de données ou gérer des calculs complexes.
- Orthogonalité des instructions : Le processeur permet d’utiliser la majorité des instructions avec divers modes d’adressage (direct, indirect, indexé, etc.), ce qui améliore la flexibilité du programmeur pour optimiser les performances.
- Instructions riches : Le 6809 introduit des instructions complexes comme MUL (multiplication), ce qui simplifie la programmation en réduisant le nombre d’instructions nécessaires pour réaliser certaines tâches complexes.
2. Modes d’adressage puissants
Le 6809 offre une grande variété de modes d’adressage, incluant des modes rarement disponibles sur d’autres processeurs 8 bits de l’époque :
- Adressage indexé : Le 6809 permet des opérations avec des adresses indexées (calculées à partir d’un registre d’index), ce qui simplifie le traitement des tableaux et des structures de données.
- Adressage indirect avec post-incrémentation et pré-décrémentation : Ces modes d’adressage permettent de manipuler les pointeurs et de parcourir des tableaux en mémoire de manière très efficace, sans avoir à écrire du code supplémentaire pour gérer l’incrémentation ou la décrémentation manuelle des adresses.
- Accès à la pile facile : Les modes d’adressage liés à la pile (par exemple, auto-indexé ou auto-déréférencé) facilitent la gestion des sous-programmes, des appels de fonction et des contextes d’interruption.
3. Registres multiples et versatiles
Contrairement à d’autres processeurs 8 bits plus limités en termes de registres (comme le 6502 avec ses trois principaux registres : A, X, Y), le 6809 dispose d’une variété de registres 8 bits et 16 bits, offrant plus de flexibilité pour la gestion des données.
- Registres de données multiples : Le 6809 dispose de deux accumulateurs 8 bits (A et B), qui peuvent être combinés en un seul registre 16 bits appelé D. Cela permet à la fois de travailler sur des octets et des mots (16 bits).
- Registres d’index X et Y : Le 6809 dispose de deux registres d’index (X et Y), offrant des possibilités supplémentaires pour le traitement des tableaux, des structures ou des adresses mémoire.
- Registres de pile multiples : Le processeur dispose de deux registres de pile (S et U), l’un dédié à la pile système et l’autre à la pile utilisateur, ce qui simplifie la gestion des appels de sous-programmes et des interruptions.
4. Interruption avancée et gestion des priorités
Le 6809 introduit un système d’interruption sophistiqué, avec la gestion des priorités et des types d’interruption distincts :
- Interruption masquable (IRQ) : Permet de traiter des événements périphériques tout en laissant au programmeur le choix de les ignorer temporairement si nécessaire.
- Interruption non masquable (NMI) : Utilisée pour les événements critiques qui nécessitent une attention immédiate du processeur, comme des erreurs matérielles.
- Interruption de type FIRQ (Fast Interrupt Request) : C’est une interruption rapide qui utilise un contexte d’interruption plus léger, ce qui permet de réduire le temps nécessaire à la gestion des interruptions. Cela est particulièrement utile dans les systèmes en temps réel.
5. Instruction « MUL » et instructions spécifiques
Le 6809 est l’un des rares processeurs 8 bits à inclure une instruction de multiplication (MUL). Cette instruction effectue une multiplication rapide entre deux registres 8 bits et stocke le résultat dans un registre 16 bits. Cela permet de gagner du temps par rapport à des implémentations logicielles plus lentes sur d’autres processeurs.
De plus, le 6809 dispose d’instructions spécifiques à la gestion de la pile, des sauts conditionnels, et des appels de sous-programmes, ce qui rend le développement en assembleur plus facile et plus rapide.
6. Gestion avancée de la mémoire
Le 6809 supporte des adresses 16 bits, ce qui permet de gérer jusqu’à 64 Ko d’adresses mémoire, typique des systèmes 8 bits de l’époque. Cependant, l’implémentation de modes d’adressage indirects et indexés permet une utilisation plus efficace de la mémoire. De plus, le processeur prend en charge des pages de mémoire pour faciliter l’accès à des blocs mémoires séparés.
7. Conçu pour la programmation en langage de haut niveau
Le 6809 a été conçu pour faciliter la programmation en langage de haut niveau comme le C ou le Pascal, contrairement à d’autres processeurs 8 bits principalement orientés vers l’assembleur. Sa conception simplifie la génération de code efficace en compilant des langages de haut niveau.
Les avantages pour la programmation en C incluent :
- Une meilleure gestion des sous-programmes, avec des piles système et utilisateur dédiées.
- L’utilisation de registres multiples pour les paramètres des fonctions et les retours de valeurs.
- Des modes d’adressage facilitant le passage d’arguments par adresse.
8. Faible complexité de conception et faible consommation d’énergie
En comparaison avec les microprocesseurs 16 bits de l’époque, comme le 8086, le 6809 offre un bon compromis entre performances et simplicité. Sa consommation d’énergie relativement faible le rend idéal pour des applications embarquées et industrielles, où l’efficacité énergétique est primordiale.
Conclusion
Le 6809 offre des avantages significatifs par rapport à d’autres microprocesseurs 8 bits de son époque. Ses instructions avancées, ses modes d’adressage sophistiqués, ses registres polyvalents et son support des interruptions en font un processeur puissant et flexible, particulièrement adapté aux systèmes embarqués et aux projets nécessitant une gestion précise des ressources matérielles. Sa conception facilitant l’utilisation de langages de haut niveau en fait également un bon choix pour des applications plus complexes où l’assembleur seul serait trop contraignant.
FAQ Microprocesseur 6809
Réponses courtes, utiles et orientées pratique autour des sujets les plus recherchés sur la programmation assembleur 6809.
Quels sont les modes d’adressage du 6809 et comment les reconnaître dans un exercice ?
Vous repérez l’adressage à la forme de l’opérande : # indique l’immédiat, une adresse courte vise souvent la page directe, une adresse complète correspond à l’étendu, et l’indexé utilise généralement un registre (X, Y, U ou S). La meilleure méthode consiste à coder la même lecture/écriture mémoire en plusieurs modes pour comparer le résultat, la taille et la rapidité.
À quoi servent les registres A, B, D, X, Y, U, S, DP et CC sur 6809 ?
Vous utilisez A et B pour les opérations 8 bits, D pour le 16 bits (A:B), X et Y pour adresser et parcourir la mémoire, U et S pour gérer la pile, DP pour accélérer l’accès à la page directe, et CC pour les drapeaux (tests, branches, comparaisons).
Comment utiliser PSHS / PULS pour écrire des sous-programmes propres ?
Vous sauvegardez en entrée les registres que votre routine va modifier (par exemple A, B, X), puis vous les restaurez juste avant le retour. Cette discipline rend vos corrigés “TP” plus clairs et évite les effets de bord. Pensez aussi à documenter ce que la routine “consomme” et “rend”.
Quelle méthode simple pour passer des paramètres à une routine (JSR/RTS) sur 6809 ?
Vous pouvez passer des paramètres via des registres (rapide et lisible), via la mémoire (variables), ou via la pile (plus “générique”). En exercice, la solution la plus pédagogique consiste à annoncer clairement le contrat : “entrée” (ex : X pointe vers un tableau) et “sortie” (ex : A contient le résultat).
Comment fonctionnent les interruptions (IRQ, FIRQ, NMI, SWI) et que doit contenir une ISR ?
Une interruption déclenche l’exécution d’une routine dédiée (ISR). Vous y appliquez une règle simple : sauvegarder ce que vous modifiez, faire une action courte (ex : acquitter un événement), puis restaurer et revenir. En TP, l’objectif est la stabilité : une ISR doit rester courte, déterministe et bien commentée.
Où se trouvent les vecteurs d’interruption et comment les initialiser ?
Les vecteurs d’interruption correspondent à des adresses en mémoire qui pointent vers vos routines. Pour un exercice, vous retenez l’idée essentielle : vous placez l’adresse de votre ISR dans le vecteur approprié, puis vous activez ce qui doit l’être (selon le contexte matériel/moniteur). Le plus important, c’est de vérifier que votre ISR se déclenche et qu’elle revient correctement.
Quelles instructions 6809 faut-il maîtriser en priorité pour réussir les exercices ?
Vous gagnez vite en efficacité avec : LDA/LDB/LDD et STA/STB/STD (données), ADDA/SUBA (calcul), CMP (comparaison), BEQ/BNE et branches associées (contrôle), JSR/RTS (routines), PSHS/PULS (pile). Avec ces bases, vous couvrez la majorité des sujets de TP.
Comment réussir un exercice sur l’adressage indexé avancé (offset, parcours mémoire) ?
Vous partez d’un registre pointeur (X ou Y), vous définissez clairement l’unité (octet ou mot), puis vous avancez de façon régulière. En corrigé, vous montrez une boucle simple : initialisation du pointeur, traitement de l’élément courant, incrément, test de fin. Cette structure fonctionne pour les tableaux, les copies et les recherches.
Quels exercices classiques de tableaux en mémoire reviennent le plus en TP 6809 ?
Vous retrouvez souvent : somme d’un tableau d’octets, recherche d’un maximum/minimum, comptage d’occurrences, copie d’un bloc mémoire, et comparaison de deux zones. Ce sont des exercices parfaits pour travailler l’indexé, les branches et la rigueur de boucle.
Comment éviter les erreurs fréquentes en branchements et comparaisons (CC) ?
Vous gagnez en fiabilité en procédant toujours dans le même ordre : comparaison, choix du bon branchement, commentaire sur la condition, puis test rapide sur un cas “vrai” et un cas “faux”. En TP, vous ajoutez un exemple chiffré (valeurs d’entrée) pour valider le chemin de code.
À quoi sert l’IO mémoire-mappée et comment l’aborder sans matériel ?
Vous traitez une adresse mémoire comme un “périphérique” : lire ou écrire à cette adresse déclenche un comportement externe. Même sans matériel, vous pouvez vous entraîner avec un scénario : une adresse représente un registre de statut, une autre une donnée. L’essentiel est de garder un code court, bien commenté et testable.
