đŸ–„ïž Correction TP2 - Assembleur 6800/6811

Approfondissemennt - Arithmétique avancée et ruptures de séquence

📊 Partie A - ArithmĂ©tique AvancĂ©e

A.1 - Dépassement de capacité et flags N, V, C

Exercice A.1.1 - Dépassement lors d'une addition (nombres non signés)

Q1.a) Prédictions

RĂ©sultat de 200₁₀ + 100₁₀ sur 9 bits : 300₁₀ = 100101100₂

Dans le registre A (8 bits) : 00101100₂ (on garde seulement les 8 bits de poids faible)

En hexadĂ©cimal : 2C₁₆

En dĂ©cimal : 44₁₀

Q1.b) Code machine

0000: 86 C8 8B 64 B7 00 20

86 C8 : ldaa #200 (C8₁₆ = 200₁₀)

8B 64 : adda #100 (64₁₆ = 100₁₀)

B7 00 20 : staa sum

Q1.c) Exécution pas à pas

Instruction A (hexa) A (décimal) Flag N Flag V Flag C
ldaa #200 C8 200 1 0 0
adda #100 2C 44 0 0 1

Q1.d) Analyse

Le registre A contient : 2C (hexa) = 44 (décimal)

Le flag C vaut : 1

Conclusion : Le résultat est incorrect car il y a eu un dépassement. Le flag C=1 indique qu'une retenue a été générée.
Pour obtenir le rĂ©sultat correct, il faut calculer : C × 256 + sum = 1 × 256 + 44 = 300

💡 Point clĂ© : Quand C=1, cela signifie qu'il y a eu un dĂ©passement de capacitĂ© pour des nombres non signĂ©s. Le rĂ©sultat rĂ©el est sur 9 bits.

Exercice A.1.2 - Dépassement avec nombres signés (flag V)

Q2.a) Test avec 127 + 1

Instruction A (hexa) A (décimal signé) N V C
adda #1 80 -128 1 1 0

Q2.b) Interprétation

Le registre A contient : 80₁₆ = -128 (dĂ©cimal signĂ©)

Flag V = 1 : Indique un dépassement en arithmétique signée

Flag N = 1 : Indique un nombre négatif

Explication : 127 + 1 = 128, mais en complément à 2 sur 8 bits, 128 n'est pas représentable (max = 127). Le résultat "déborde" et devient -128.

Q2.c) Test avec v1=-128 et v2=-1

Instruction A (hexa) A (signé) N V C
adda v2 7F 127 0 1 1

Q2.d) Interprétation

Le registre A contient : 7F₁₆ = 127 en dĂ©cimal signĂ©

Flag V = 1 : Indique un dépassement en arithmétique signée

Flag N = 0 : Indique un nombre positif

Explication : -128 + (-1) = -129, qui n'est pas représentable sur 8 bits signés (min = -128). Le résultat déborde et devient 127.

⚠ Important : Le flag V dĂ©tecte les dĂ©passements pour les nombres SIGNÉS, tandis que le flag C dĂ©tecte les dĂ©passements pour les nombres NON SIGNÉS.

A.2 - Le résultat de l'opération est nul et flag Z

Exercice A.2 - Résultat nul et flag Z

Q3.a) Test avec v1=-1 et v2=1

Instruction A (hexa) A (décimal signé) N Z V C
staa sum 00 0 0 1 0 1

Q3.b) Interprétation

La case mĂ©moire contient : 00₁₆

Flag Z = 1 : Indique que le résultat est exactement zéro

Explication : -1 + 1 = 0, le flag Z est positionné à 1 pour indiquer ce résultat nul.

✅ Points clĂ©s Ă  retenir :
  • Z=1 : Le rĂ©sultat est exactement zĂ©ro (trĂšs utile pour les boucles !)
  • N=1 : Le bit 7 est Ă  1, nombre nĂ©gatif en complĂ©ment Ă  2
  • V=1 : DĂ©passement de capacitĂ© pour opĂ©ration signĂ©e (rĂ©sultat < -128 ou> 127)
  • C=1 : DĂ©passement de capacitĂ© pour opĂ©ration non signĂ©e (rĂ©sultat < 0 ou> 255)

A.3 - Multiplication en machine

Exercice A.3.1 - Multiplication en machine

Q4.a) Exécution pas à pas

Instruction A (hexa) B (hexa) D (hexa) Commentaire
ldaa v1 0A 00 0A00 A = 10₁₀
ldab v2 0A 28 0A28 B = 40₁₀
mul 01 90 0190 10₁₀ × 40₁₀ = 400₁₀
staa v3H 01 90 0190 V3H = 01₁₆
stab v3L 01 90 0190 V3L = 90₁₆

Q4.b) Analyse

v3H contient : 01 (hexa)

v3L contient : 90 (hexa)

Le résultat complet v3 : v3H|v3L = 0190 (hexa)

Conversion en dĂ©cimal : 0190₁₆ = 1×256 + 144 = 400₁₀

Conclusion : Oui, le résultat est correct !

Q4.c) Code source et code machine (programme exécuté)

Code machine Code source assembleur
Address Opcode Operand [Label] operation [operand] [comment]
.org $0000 ; origine du programme en mémoire
0000 B6 00 20 ldaa v1 ; [A] ← [v1]
0003 F6 00 21 ldab v2 ; [B] ← [v2]
0006 3D - mul ; [D] ← [A] × [B] (D = A|B sur 16 bits)
0007 B7 00 22 staa v3H ; [v3H] ← [A]
000A F7 00 23 stab v3L ; [v3L] ← [B]
.org $0020 ; origine des données en mémoire (variables)
0020 0A v1 .byte 10 ; Premier facteur
0021 28 v2 byte 40 ; DeuxiĂšme facteur
0022 01 v3H .byte 0 ; Premier octet du résultat
0023 90 v3L .byte 0 ; DeuxiÚme octet du résultat
💡 Point important : L'instruction MUL n'existe que sur le MC6811, pas sur le MC6800 ! Le rĂ©sultat 16 bits est stockĂ© dans le registre double D (D = A|B).

🔄 Partie B - Instructions de rupture de sĂ©quence

B.1 - Introduction aux sauts

Exercice B.1.1 - Saut inconditionnel (BRA : BRanch Always)

Q5. Exécution pas à pas

Instruction PC avant PC aprĂšs A Commentaire
ldaa #5 0000 0002 05 A = 5
bra suite 0002 0006 05 PC saute à l'étiquette suite !
ldaa #10 ⚠ Non exĂ©cutĂ©e
suite staa resultat 0006 0009 05 Suite du prog.

Conclusion : L'instruction BRA provoque un branchement inconditionnel. Elle saute toujours, sans tester de condition.

Exercice B.1.2 - Branchement conditionnel (BEQ : Banch if EQqual to zero)

Test 1 : data = 0

Q6. Complétez le tableau

Instruction A Flag Z Branchement ? Chemin pris
ldaa data 00 1 - -
beq estnul 00 1 OUI estnul

Valeur finale dans resultat : 00

Test 2 : data = 5

Q7. Complétez le tableau

Instruction A Flag Z Branchement ?
ldaa data 05 0 -
beq estnul 05 0 NON

Valeur finale dans resultat : 01

Conclusion :

  • BEQ branche si et seulement si Z = 1
  • Cela correspond Ă  un rĂ©sultat Ă©gal Ă  zĂ©ro

Exercice B.2.1 - Compte Ă  rebours (BNE : Banch if Not Equal to zero)

Prédictions

Nombre de fois que la boucle s'exécute : 5 fois

Valeur finale de cmpt : 00

Q8. Tableau d'exécution de la boucle

Passage A avant DECA A aprĂšs DECA Flag Z Branchement ? Commentaire
1 05 04 0 OUI Continue
2 04 03 0 OUI Continue
3 03 02 0 OUI Continue
4 02 01 0 OUI Continue
5 01 00 1 NON Sort de la boucle

Conclusion : Pour sortir de la boucle, il faut que Z = 1 (condition de BNE).

BNE signifie "Branch if Not Equal to zero", donc on continue tant que Z=0 et on sort quand Z=1.

Algorigramme de la boucle

DĂ©but [A] ← 5 loop [A] ← [A] - 1 [A] ≠ 0 (Z = 0) ? OUI NON [cmpt] ← [A] Fin
📊 Explication de l'algorigramme :
  • Terminateur (ellipse) : DĂ©but et Fin du programme
  • Traitement (rectangle) : OpĂ©rations d'affectation ([A] ← 5, [A] ← [A] - 1)
  • Test (losange) : Condition de boucle ([A] ≠ 0 ?)
  • Étiquette (rectangle arrondi) : Point de retour de la boucle (loop)
  • FlĂšches : Sens d'exĂ©cution (verte = OUI, rouge = NON)

B.3 - Boucles avec adressage indexé

Exercice B.3.1.1 - Découverte du registre X et adressage indexé

Q9. Tableau d'exécution

Instruction X (hexa) A (hexa) B (hexa) Donnée pointée Adresse
ldx #data 0020 - - 0A (10) 0020
ldaa 0,X 0020 0A - 0A (10) 0020
inx 0021 0A - 14 (20) 0021
ldab 0,X 0021 0A 14 14 (20) 0021
inx 0022 0A 14 1E (30) 0022
ldaa 0,X 0022 1E 14 1E (30) 0022

Conclusion :

  • Le registre X contient une adresse
  • L'instruction LDAA 0,X signifie : lire la donnĂ©e Ă  l'adresse 0 + [X]
  • INX permet de passer Ă  l'octet suivant
💡 Adressage indexĂ© vs adressage Ă©tendu :
; Mode étendu (adresse fixe)
ldaa $0020 ; [A] ← [0020] : Affecter le contenu de la mĂ©moire situĂ©e Ă  l'adresse fixe 0020₁₆ au registre A
; Mode indexé (adresse variable)
ldx #$0020 ; [X] ← 0020₁₆ : Affecter la valeur 0020₁₆ au registre X
ldaa 0,X ; [A] ← [0+[X]] : Affecter le contenu de la mĂ©moire situĂ©e Ă  l'adresse 0 + [X] = 0020₁₆ au registre A
inx ; [X] ← [X] + 1
ldaa 0,X ; [A] ← [0+[X]] : Affecter le contenu de la mĂ©moire situĂ©e Ă  l'adresse 0 + [X] = 0021₁₆ au registre A

Avantage : L'adresse change dynamiquement → parfait pour les boucles !

Exercice B.3.2 - ChaĂźnes de caractĂšres

Q10. Parcours fixe (5 caractĂšres)

Passage X (hexa) A (hexa) B (hexa) CaractĂšre
1 0020 48 5 'H'
2 0021 65 4 'e'
3 0022 6C 3 'l'
4 0023 6C 2 'l'
5 0024 6F 1 'o'
⚠ ProblĂšme : Cette mĂ©thode nĂ©cessite de connaĂźtre la longueur de la chaĂźne Ă  l'avance !

Q11. Détection du caractÚre NUL

a) Algorigramme complété

L'algorigramme montre :

  1. [X] ← msg (initialisation du pointeur)
  2. Début de la boucle (loop)
  3. [A] ← [0 + [X]] (lire le caractĂšre pointĂ©)
  4. Test : [A] = 0 ? (Z=1 ?)
  5. Si OUI → brancher Ă  suite (fin de chaĂźne dĂ©tectĂ©e)
  6. Si NON → [X] ← [X] + 1 (passer au caractùre suivant)
  7. Retour Ă  loop

b) Code assembleur complété

ldx #msg ; X ← adresse de msg
loop ldaa 0,X ; A ← [0+[X]]
cmpa #0 ; (A = 0 (Z=1)?)
beq suite ; si oui alors branchement Ă  suite
inx ; sinon X ← X + 1
bra loop ; branchement Ă  loop
suite ; suite du programme

c) Fichier finchaine.asm complété

; SDK6811 - finchaine.asm
; Détection de fin de chaßne
.org $0000
ldx #msg ; X pointe sur le premier caractĂšre
loop ldaa 0,X ; Lire le caractĂšre
cmpa #0 ; Comparer avec NUL
beq suite ; Si NUL, sortir de la boucle
inx ; Sinon, passer au suivant
bra loop ; Continuer
suite ; Fin du parcours
.org $0020
msg .str "Hello" ; ChaĂźne avec NUL automatique

d) Affichage dans le simulateur

Pour afficher "Hello" dans l'onglet du simulateur, il faut utiliser transférer chaque caractÚre de la zone mémoire $0020:$0024 à la zonne mémmoire $FB00:$fb04.

; SDK6811 - hello.asm
; Affichage de la chaĂźne "Hello" dans le simulateur
ecran .equ $fb00 ; Déclaration d'une constante
.org $0000
ldx #msg ; X pointe sur le premier caractÚre dans la mémoire
ldy #ecran ; Y pointe sur la position (0,0) sur l'écran du simulateur
loop ldaa 0,X ; Lire le caractĂšre
cmpa #0 ; Comparer avec NUL
beq suite ; Si NUL, sortir de la boucle
inx ; Passer au caractĂšre suivant
iny ; Passer Ă  la position suivante
staa 0,y ; Afficher le caractÚre à l'écran
bra loop ; Continuer
suite nop ; Fin du parcours
.org $0020
msg .str "Hello"
✅ Points clĂ©s Ă  retenir sur les chaĂźnes :
  • Une chaĂźne de caractĂšres est terminĂ©e par le caractĂšre NUL (00₁₆)
  • La directive .str ajoute automatiquement le NUL
  • On utilise le registre X comme pointeur pour parcourir la chaĂźne
  • On teste chaque caractĂšre pour dĂ©tecter la fin (cmpa #0)
  • Cette technique Ă©vite de devoir connaĂźtre la longueur Ă  l'avance

📝 RĂ©capitulatif des flags et instructions

Les 4 flags principaux

Flag Nom Signification Utilisé pour
Z Zero Résultat = 0 Tester l'égalité, détecter la fin de boucle
N Negative Bit 7 = 1 Détecter un nombre négatif (complément à 2)
V oVerflow Dépassement signé Détecter dépassement en arithmétique signée
C Carry Retenue Détecter dépassement en arithmétique non signée

Instructions de branchement

Instruction Signification Condition Utilisation
BRA Branch Always Toujours Saut inconditionnel
BEQ Branch if Equal Z = 1 Brancher si résultat = 0
BNE Branch if Not Equal Z = 0 Brancher si rĂ©sultat ≠ 0 (boucles)

Modes d'adressage vus

Mode Syntaxe Exemple Description
Immédiat #valeur ldaa #200 Charger une valeur directe
Étendu adresse ldaa $0020 Lire à une adresse fixe
Indexé offset,X ldaa 0,X Lire à l'adresse offset + [X]
💡 Conseil pour les boucles :

Pour créer une boucle efficace :

  1. Initialiser un compteur ou un pointeur
  2. Créer une étiquette pour le début de la boucle
  3. Effectuer les opérations souhaitées
  4. Modifier le compteur/pointeur (DECA, INX...)
  5. Tester la condition de sortie
  6. Brancher conditionnellement au début (BNE, BEQ...)