Version sans JavaScript, en lecture seule : les ateliers, les quiz et l’exécution du code n’y sont pas. Version complète · Catalogue · Se connecter
Support de cours · chapitre 4
Tests, sauts et boucles
Comparer, sauter selon les indicateurs, et traduire en assembleur les si, les tant que et les pour d'un langage de haut niveau.
Sauter
Le saut inconditionnel
BRA ETIQ (branch always) écrit l'adresse de ETIQ dans PC : l'exécution continue là. C'est le goto des langages de haut niveau, et c'est le seul moyen de revenir en arrière pour faire une boucle.
Comparer
Un branchement conditionnel ne teste rien lui-même : il lit les indicateurs laissés par l'instruction précédente. On les positionne avec :
| Instruction | Calcule | Pour |
|---|---|---|
CMP.t src,Dk | Dk − src, sans ranger le résultat | comparer Dk à src |
CMPI.t #n,dst | dst − n | comparer à une constante, en mémoire ou en registre |
TST.t dst | dst − 0 | savoir si dst est nul, négatif ou positif |
Beaucoup d'instructions positionnent déjà les indicateurs : après MOVE.W X,D0, on sait si X est nul ou négatif sans TST.
Les branchements conditionnels
Après CMP src,dst, le branchement Bcc ETIQ saute à ETIQ si la condition est vraie, et continue à la ligne suivante sinon.
| Saute si | En signé | En non signé |
|---|---|---|
dst = src | BEQ | BEQ |
dst ≠ src | BNE | BNE |
dst > src | BGT | BHI |
dst ≥ src | BGE | BHS (ou BCC) |
dst < src | BLT | BLO (ou BCS) |
dst ≤ src | BLE | BLS |
Et, après n'importe quelle instruction : BMI si le résultat est négatif (N = 1), BPL s'il est positif ou nul, BVS s'il y a eu débordement.
Traduire les structures de contrôle
La règle de toutes les traductions : on saute quand la condition est fausse, pour passer par-dessus le bloc qu'elle protège.
Si… sinon
* si (X = 0) alors Y <- 1 sinon Y <- 2
TST.W X
BNE SINON ; condition fausse : aller au sinon
MOVE.W #1,Y ; alors
BRA FINSI ; ne pas exécuter le sinon
SINON MOVE.W #2,Y ; sinon
FINSI
Sans le BRA FINSI, le programme exécuterait aussi le bloc « sinon » après le bloc « alors ».
Tant que
* tant que (D0 < 100) faire D0 <- 2 * D0
TANTQUE CMP.W #100,D0 ; D0 - 100
BGE FINTQ ; condition fausse (D0 >= 100) : sortir
ADD.W D0,D0 ; corps de la boucle
BRA TANTQUE ; retour au test
FINTQ
Pour, avec DBRA
Le 68000 a une instruction faite pour les boucles comptées : DBRA Dk,ETIQ retire 1 au mot bas de Dk, puis saute à ETIQ si Dk.W ne vaut pas −1. Pour répéter un corps $n$ fois, on initialise le compteur à $n - 1$.
* somme des N mots du tableau TAB
N EQU 10
LEA TAB,A0
CLR.W D0 ; somme
MOVE.W #N-1,D1 ; N tours : compteur de N-1 à 0
BCL ADD.W (A0)+,D0
DBRA D1,BCL
MOVE.W D0,SOMME
Une boucle sur une chaîne
Une chaîne se termine par un octet nul. Sa longueur se calcule en avançant jusqu'à ce zéro :
* D0 <- longueur de la chaîne pointée par A0
MOVEQ #0,D0
BCL TST.B (A0)+ ; octet nul ? (A0 avance de 1)
BEQ FIN
ADDQ.L #1,D0
BRA BCL
FIN
On ne connaît pas le nombre de tours à l'avance : c'est un « tant que », pas un « pour », d'où le BRA plutôt que DBRA.
À essayer
Le même calcul, en programme complet, qui affiche la longueur avec le service 3 de TRAP #15. Changez la chaîne, exécutez, et vérifiez la longueur affichée ; puis suivez-la pas à pas en regardant A0 avancer d'un octet à chaque tour.
ORG $1000
START LEA CH,A0 ; A0 pointe sur la chaîne
MOVEQ #0,D1 ; longueur
BCL TST.B (A0)+ ; octet nul ? (A0 avance de 1)
BEQ FIN
ADDQ.L #1,D1
BRA BCL
FIN MOVE.B #3,D0 ; service 3 : afficher D1.L
TRAP #15
SIMHALT
CH DC.B 'Bonjour',0
END START