Apprendre à programmer

Exercices de Programmation Corrigés sur le Microprocesseur 6809

×

Recommandés

Guide : Liste de Tableaux C# vs...
En C#, une liste de Tableaux...
En savoir plus
Guide : Liste de Tableaux en C#
En C#, une liste de tableaux...
En savoir plus
Guide : Python - Concatenation de chaînes...
La concaténation de chaînes de caractères...
En savoir plus
Utilisation des Pointeurs en C dans des...
Les pointeurs en C sont un...
En savoir plus
Série d’Exercices Corrigés : Manipulation de Tableaux...
Cette série d'exercices se concentre sur...
En savoir plus
Programmation ISO (ou G-code) : Guide
La programmation ISO (ou G-code) est...
En savoir plus

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.

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.

1) Code source assembleur (.asm)
main.asm
; Exemple 6809
ORG $1000
LDA  #$2A
STA  $2000
BRA  LOOP
LOOP: NOP
      BRA LOOP
        
Vous écrivez des mnémotechniques, des labels et des directives : c’est lisible, mais pas encore exécutable.
2) Assembleur
Ce qu’il fait
  • Analyse le texte (syntaxe)
  • Résout les labels (adresses)
  • Traduit en opcodes
  • Produit binaire + listing + symboles
Résultat
Vous passez d’un code lisible à une suite d’octets exécutables par le microprocesseur.
3) Sorties
Binaire (.bin / .hex)
Octets exécutables.
Listing (.lst)
Adresse → instruction → opcode.
Symboles (.sym)
Labels, constantes, adresses.
4) Chargement et exécution (CPU)
Ce que le 6809 “voit”
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.
          
Vous chargez le binaire (émulateur, moniteur, ROM/RAM), puis vous observez l’effet sur les registres et la mémoire.

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 programme

Explication :

  • ORG $1000 : Définit l’origine de l’assemblage à l’adresse mémoire $1000.
  • LDA $1000 : Charge la valeur stockée à l’adresse $1000 dans 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 programme

Explication :

  • 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 (1 ou 0) 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 programme

Explication :

  • 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 programme

Explication :

  • LDA $4000 : Lire l’état du bouton connecté au port A du PIA.
  • CMPA #1 : Comparer avec 1 pour 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 0 dans 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'interruption

Explication :

  • 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.

Recommandés

Guide : Liste de Tableaux C# vs...
En C#, une liste de Tableaux...
En savoir plus
Guide : Liste de Tableaux en C#
En C#, une liste de tableaux...
En savoir plus
Guide : Python - Concatenation de chaînes...
La concaténation de chaînes de caractères...
En savoir plus
Utilisation des Pointeurs en C dans des...
Les pointeurs en C sont un...
En savoir plus
Série d’Exercices Corrigés : Manipulation de Tableaux...
Cette série d'exercices se concentre sur...
En savoir plus
Programmation ISO (ou G-code) : Guide
La programmation ISO (ou G-code) est...
En savoir plus
AZ

Share
Published by
AZ

Recent Posts

Simulateur LOA Matériel Pro — Estimer le leasing d’un équipement sans se raconter d’histoires

Quand on finance une voiture, tout le monde voit à peu près de quoi il…

12 heures ago

Simulateur LOA Auto — Estimer son leasing voiture sans se tromper

On connaît tous ce moment : on tombe sur une offre de leasing “à partir…

13 heures ago

Différence maintenance niveau 1, niveau 2 et niveau 3 en industrie

Dans l’industrie, parler de maintenance sans préciser le niveau d’intervention revient souvent à créer de…

18 heures ago

Maintenance 1er Niveau des Équipements Industriels : 15 pannes célèbres et méthodes de diagnostic terrain

La Maintenance 1er Niveau - maintenance de niveau 1 - représente la première barrière contre…

19 heures ago

QCM Communication Interne et Externe

Un outil simple pour mesurer la compréhension… et révéler les écarts invisibles Dans beaucoup d’organisations,…

2 jours ago

Audit de Communication Interne et Externe : Canevas Word

Le levier discret qui transforme l’image, la cohésion et la performance d’une organisation Dans beaucoup…

2 jours ago

This website uses cookies.