Les instructions de contrôle Chapitre 7 Les instructions de contrôle
La programmation structurée Les programmes sont composés de trois structures de contrôles L’itération La sélection La séquence Dans les langages évolués For, while, loop, etc. If, swicth, etc. Suite normale d’instructions En assembleur, il faut les simuler À l’aide des branchements
La programmation modulaire On divise le problème en différents modules Chaque module Implémente une seule fonction A un seul point d’entrée et un seul point de sortie A une petite taille Est conçu pour être codé et tester séparément En assembleur, l’implémentation d’un module est réalisée à l’aide de sous-programmes.
Les structures de contrôles La séquence mov %l0, %l1 add %l1, %l1, %l1 mulx %l1, %l0, %l0 setx num, %l7, %l1 Suite d’instructions 𝑖𝑛𝑠 𝑡 1 𝑖𝑛𝑠 𝑡 2 ⋮ 𝑖𝑛𝑠 𝑡 𝑚
Les structures de contrôles La condition cmp %l0, %l1 bne Sinon nop add %l0, %l0, %l2 ba Apres sub %l0, %l1, %l2 … Sinon: Apres: si condition 𝑖𝑛𝑠 𝑡 1 ⋮ 𝑖𝑛𝑠 𝑡 𝑚 sinon 𝑖𝑛𝑠 𝑡 𝑚+1 𝑖𝑛𝑠 𝑡 𝑛 Branchement sous condition Branchement inconditionnel
Les structures de contrôles L’itération Debut: mov %l0, %l1 add %l0, %l0, %l2 inc 4, %l3 mulx %l2, %l3, %l4 cmp %l4, %l5 bne Debut nop … répéter 𝑖𝑛𝑠 𝑡 1 ⋮ 𝑖𝑛𝑠 𝑡 𝑚 jusqu’à condition Branchement sous condition
Les structures de contrôles Les conditions sur l’itération et la sélection sont des expressions booléennes On les calcule à l’aide D’opérations arithmétiques D’opérations logiques Ces opérations positionnent les codes de condition du registre CCR Les codes de condition sont consultés par les branchements
Les branchements Un branchement s’applique à la dernière instruction qui modifie les codes de condition Si la condition est vraie Le branchement s’exécute L’instruction à exécuter après celle dans la fente de temporisation est Celle de l’adresse de l’étiquette du branchement Sinon L’exécution se poursuit en séquence
Les branchements Un branchement s’applique à la dernière instruction qui modifie les codes de condition addcc subcc … cmp tst
Les branchements Les conditions « simples » Instructions Signification ba Branch Always vrai inconditionnel bn Branch Never faux jamais bnz Branch Not Zero ¬𝑍 ≠0 bne Branch Not Equal 𝐴≠𝐵 be Branch Equal 𝑍 𝐴=𝐵 bz Branch Zero =0 bcc Branch Carry Clear ¬𝐶 Si pas de report bcs Branch Carry Set 𝐶 Si report bvc Branch oVerflow Clear ¬𝑉 Si pas de débordement bvs Branch oVerflow Set 𝑉 Si débordement bpos Branch POSitive ¬𝑁 ≥0 bneg Branch NEGative 𝑁 <0
Les branchements Suite à des instructions arithmétiques signées Suite à des instructions arithmétiques non signées Unsigned Instructions Signification Condition bg Branch Greater ¬(𝑍∨ 𝑁⊕𝑉 ) 𝐴>𝐵 bge Branch Greater or Equal ¬(𝑁⊕𝑉) 𝐴≥𝐵 bl Branch Less 𝑁⊕𝑉 𝐴<𝐵 ble Branch Less or Equal 𝑍∨(𝑁⊕𝑉) 𝐴≤𝐵 Instructions Signification Condition bgu Branch Greater ¬(𝐶∨𝑍) 𝐴>𝐵 bgeu Branch Greater or Equal ¬𝐶 𝐴≥𝐵 blu Branch Less 𝐶 𝐴<𝐵 bleu Branch Less or Equal 𝐶∨𝑍 𝐴≤𝐵
Les branchements Explication des conditions 𝐴≤𝐵⇒𝐴−𝐵≤0 Si 𝐴−𝐵=0→𝑍=1⇒𝑍∨ 𝑁⊕𝑉 =1 Sinon, un débordement est possible Si V=0 Si 𝑁=1 alors 𝐴−𝐵<0, 𝐴<𝐵→𝑍∨ 𝑁⊕𝑉 =1 Si 𝑁=0 alors 𝐴−𝐵>0, 𝐴>𝐵→𝑍∨ 𝑁⊕𝑉 =0 Si 𝑉=1 Si 𝑁=1 alors 𝐴−𝐵<0, 𝐴>0 et 𝐵<0→𝐴>𝐵→𝑍∨ 𝑁⊕𝑉 =0 Si 𝑁=0 alors 𝐴−𝐵>0, 𝐴<0 et 𝐵>0→𝐴<𝐵→𝑍∨ 𝑁⊕𝑉 =1 ble Branch Less or Equal 𝑍∨(𝑁⊕𝑉) 𝐴≤𝐵
Les branchements Explication des conditions ¬ 𝐶∨𝑍 =¬𝐶∧¬𝑍→𝐶=0 et 𝑍=0 𝐴>𝐵→ 𝐴−𝐵 s’effectue sans emprunt (𝐶=0) 𝐴>𝐵→𝐴≠𝐵→ 𝐴−𝐵 ≠0→𝑍=0 bgu Branch Greater Unsigned ¬(𝐶∨𝑍) 𝐴>𝐵
Les branchements La forme générale d’un branchement est Si le « a » (annulation) est présent Sur un branchement inconditionnel L’instruction dans la fente de temporisation est toujours annulée Sur un branchement conditionnel Si le branchement s’effectue L’instruction dans la fente de temporisation est exécutée Si le branchement ne s’effectue pas L’instruction dans la fente de temporisation ne s’exécute pas Le « a » est optionnel Doit être utilisé avec précaution! bXXXX,a, pt cc, etiquette
Les branchements La forme générale d’un branchement est Le paramètre « p » peut prendre deux valeurs pt : Prédit que le branchement a lieu pn : Prédit que le branchement n’aura pas lieu On laisse le compilateur s’occuper de ce paramètre Par défaut, vaut pt Le paramètre « cc » indique quels codes de condition utiliser icc : Entiers sur 32 bits xcc : Entiers sur 64 bits bXXXX,a, p cc, etiquette
Les branchements 𝑐= max 𝑎,𝑏 | 𝑎→%𝑙1, 𝑏→%𝑙2, 𝑐→%𝑙3 cmp %l1, %l2 ! Comparaison de %l1 et %l2 bg,a etiq ! Si %l1 > %l2 ? mov %l1, %l3 ! Exécutée si A > B C = A %l2, %l3 ! Exécutée si A <= B C = B etiq: cmp %l1, %l2 ! Comparaison de %l1 et %l2 bg etiq ! Si %l1 > %l2 ? mov %l1, %l3 ! C = A %l2, %l3 ! C = B etiq:
Adresse éloignée Sur le SPARC, un branchement ne peut contenir qu’un déplacement de 22 bits Si l’adresse cible est trop loin, on doit utiliser une alternative Saut inconditionnel, avec registre jmp %l0 Instruction synthétique qui dérive de jmpl %l0, %g0 JuMP and Link est aussi utilisé pour les appels de sous programme
Adresse éloignée L’adresse contenue dans le registre doit Être un multiple de 4 Une instruction fait 4 octets de long! La valeur du PC est conservée dans le registre de destination Supporte le mode indexé jmp %l0 + %l1
Sous-programmes Suites d’instructions exécutables à partir de n’importe quel point d’un programme Si le sous-programme s’appelle lui-même, on dit qu’il est récursif Comporte trois parties Sauvegarde des données critiques du programme appelant Traitement Rétablissement de l’état du programme appelant et retour
Sous-programmes Aspects à considérer pour écrire un sous-programme Appel et retour Passage des paramètres d’entrée/sortie et valeur de retour Sauvegarde et rétablissement des registres de l’appelant
Appel et retour L’appel est réalisé à l’aide d’un branchement à l’adresse du sous-programme On doit cependant conserver l’adresse de retour C’est le lien entre un appelant et un appelé setx spgm, %l7, %l0 jmpl %l0, %o7 nop … jmp %o7+8 spgm: %o7 = PC setx spgm, %l7, %l0 jmpl %l0, %o7 nop … spgm: jmp %o7+8
Appel et retour On utilise jmpl seulement si on ne connait pas l’adresse à la compilation, ce qui est rare On utilise call pour l’appel On utilise retl pour le retour … call spgm nop retl spgm: %o7 = PC call spgm nop … spgm: retl
Passage des paramètres Il y a trois façons de passer des paramètres Par adresse Le paramètre reçu est l’adresse d’une valeur. Le sous-programme peut donc la modifier comme il veut. Par référence Même principe que pour l’adresse. En assembleur, il n’y a pas de différence Par valeur Le sous-programme reçoit directement une copie de la valeur. Si le sous-programme la modifie, la modification n’est pas répercutée sur la valeur dans le programme appelant.
Passage des paramètres En SPARC, on utilise les registres O %o0, %o1, %o2, %o3, %o4, %o5 %o6 et %o7 sont réservés Si on a plus que cinq paramètres, on utilise une pile Vu dans le chapitre 10. La valeur de retour d’un sous-programme est habituellement récupérée dans le registre %o0 Le sous-programme la retourne donc dans son registre %i0 Fenêtre de registre!
Fenêtre de registres En SPARC, les registres sont des ressources partageables Le sous-programme doit les sauvegarder avant de les utiliser Le sous-programme doit rétablir les registres avant de terminer
Fenêtre de registres L’instruction save alloue une nouvelle fenêtre de registre La sauvegarde s’effectue dans la pile On doit réserver assez d’espace pour sauvegarder tous les registres Il est commun de réserver 208 octets sur la pile save %sp, -208, %sp Le sommet de la pile évolue vers les adresses inférieures (-208)
Fenêtre de registres Le changement de fenêtres fait en sorte que Les registres de sortie de l’appelant deviennent les registres d’entrée du sous-programme %o0 à %o7 %i0 à %i7 %sp (%o7) %fp (%i7) Le retour des résultats se fait donc dans les registres %i0 à %i5
Fenêtre de registres L’instruction restore rétablit l’ancienne fenêtre de registres restore L’utilisation d’une fenêtre de registre empêche un sous-programme d’utiliser l’instruction retl Le registre %o7 est devenu %i7! On utilise l’instruction synthétique ret Équivalent à jmp %i7+8 ret avec fenêtre de registres; retl sans fenêtre de registres
Fenêtre de registres … call spgm nop spgm: save %sp, -208, %sp ret restore … call spgm nop spgm: retl Exemple au tableau
Récursivité Un sous-programme est récursif s’il s’appelle lui-même en cours d’exécution Le concept de fenêtre facilite l’écriture de programme récursif Les données du sous-programme sont dans les registres locaux Comment afficher les données d’un tableau en ordre inverse, sans boucle?
Récursivité Afficher du dernier au premier les éléments d’un tableau, sans boucle %i0 contient l’adresse du tableau %i1 contient le nombre d’éléments du tableau %i2 contient l’indice courant dans le tableau
Récursivité Affiche: save %sp, -208, %sp ! Fenêtre de registres add %i2, 4, %o2 ! On est un élément plus loin cmp %o2, %i1 ! Est-ce qu’on est au dernier? bge Affiche10 ! Si oui, on va afficher la valeur sllx %o2, 2, %l0 ! On prépare l’index (id X 4) mov %i0, %o0 ! Sinon, on se réappelle call Affiche %i1, %o1 ! Avec les bon paramètre Affiche10: setx ptfmt1, %l7, %o0 ! L’adresse du format lduw [%i0+%l0], %o1 ! La valeur de la case courante printf ! On l’affiche nop ! … ret ! Retourne à l’appelant restore ! Restauration des registres