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 :

InstructionCalculePour
CMP.t src,DkDk − src, sans ranger le résultatcomparer Dk à src
CMPI.t #n,dstdst − ncomparer à une constante, en mémoire ou en registre
TST.t dstdst − 0savoir 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 siEn signéEn non signé
dst = srcBEQBEQ
dst ≠ srcBNEBNE
dst > srcBGTBHI
dst ≥ srcBGEBHS (ou BCC)
dst < srcBLTBLO (ou BCS)
dst ≤ srcBLEBLS

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