CHAPITRE 10 Les sous-programmes 1
Sous-programme Suite d’instructions appelée de manière répétitive Par un programme Par plusieurs programmes distincts Une seule façon de faire l’appel Sauvegarde de la valeur courante du PC Effectuer un branchement à l’adresse du sous-programme Une seule façon de faire le retour Effectuer un branchement à l’ancienne valeur du PC, à une constante près. 2
Sous-programme Un sous-programme se compose généralement de: Récupération des paramètres (inverse du passage de paramètres) Sauvegarde de l’environnement de l’appelant Traitement Retour des résultats, s’il y a lieu Rétablissement de l’environnement de l’appelant Retour vers l’appelant (inverse de l’appel) 3
Passage de paramètres Sur le SPARC On utilise l’instruction save pour sauvegarder l’environnement On peut utiliser six registres O pour le passage de paramètres. Que faire si on doit passer plus de six paramètres? Que faire si l’architecture n’offre pas de fenêtres de registres? 4
Passage de paramètres Il existe différentes façons d’effectuer le passage des paramètres Utilisation d’une fenêtre de registre (comme le SPARC) Utilisation directe des registres Utilisation de l’adresse de retour ou du registre de lien Utilisation d’une table Utilisation d’une pile 5
Fenêtre de registres Peut être utilisé lorsque l’architecture supporte le concept de fenêtre de registres 6 Pgm: mov10, %o0 mov25, %o1 callSomme mov32, %o2 mov%o0, %l6 … Somme: save%sp, -208, %sp add%i0, %i1, %i0 add%i0, %i2, %i0 ret restore
Registres Similaire à la technique précédente Ne fonctionne pas si le nombre de paramètres est plus grand que le nombre de registres. 7 Pgm: mov10, %l0 mov25, %l1 callSomme mov32, %l2 mov%l0, %l6 … Somme: add%l0, %l1, %l0 add%l0, %l2, %l0 retl nop
Adresse de retour 8
9 Pgm: callSomme nop.word10.word25.word32 mov%l0, %l6 … Somme: ldsw[%o7+8], %l0 ldsw[%o7+12], %l1 ldsw[%o7+16], %l2 add%o7, 12, %o7 add%l0, %l1, %l0 add%l0, %l2, %l0 retl nop %o7 + 8
Table On met les paramètres dans une table en mémoire On passe l’adresse de la table comme paramètre du sous- programme On peut donc indexé à partir de cette adresse pour obtenir chacun des paramètres Comme avec la méthode précédente, on peut passer un nombre arbitraire de paramètres. 10
Table 11 Pgm: setxTable, %l7, %l0 callSomme nop mov%l0, %l6 … Somme: ldsw[%l0], %l1 ldsw[%l0+4], %l2 ldsw[%l0+8], %l3 add%l1, %l2, %l0 add%l0, %l3, %l0 retl nop.section".rodata".align4 Table:.word10, 25, 32
Pile On met les paramètres au sommet d’une pile C’est le programme appelant qui s’occupe d’empiler Le programme appelant et le sous-programme ont accès à un registre qui contient l’adresse du sommet de la pile. Le sous-programme dépile les paramètres Empile le résultat sur la pile En SPARC, le registre %sp contient l’adresse du sommet de la pile C’est une pile biaisée (2047) et il faut ajouter 128 (on va voir plus tard) 12
Pile 13 Pgm: mov10, %l0 dec8, %sp stx%l0, [%sp ] mov25, %l0 dec8, %sp stx%l0, [%sp ] mov32, %l0 dec8, %sp stx%l0, [%sp ] callSomme nop ldx[%sp ], %l6 … %sp %sp-8 %sp-16 %sp-24
Pile 14 Somme: ldx[%sp ], %l3 inc8, %sp ldx[%sp ], %l2 inc8, %sp ldx[%sp ], %l1 inc8, %sp add%l1, %l2, %l0 add%l0, %l3, %l0 dec8, %sp stx%l0, [%sp ] retl nop %sp+24 %sp+16 %sp+8 %sp 67
Récursivité Il faut habituellement sauvegarder l’environnement de l’appelant lors de l’exécution d’un sous-programme On utilise généralement une pile C’est d’autant plus vrai pour les sous-programmes récursifs Si l’architecture ne fournit qu’une seule fenêtre de registres Il faut sauvegarder tous les registres que le sous-programme modifie L’endroit le plus adapté est la pile Sur le SPARC, le changement de fenêtre de registres règle le problème 15
Récursivité 16 Factoriel: dec8, %sp stx%o7, [%sp ] dec8, %sp stx%o1, [%sp ] dec8, %sp stx%l0, [%sp ] dec8, %sp stx%l1, [%sp ] brz,a%o1, fact05 mov1, %o0 mov%o1, %l0 sub%o1, 1, %o1 callFactoriel nop %o7 %o1 %l0 %l1 %sp %sp-8 %sp-16 %sp-24 %sp-32
Récursivité 17 brz,a%o0, fact05 nop mulx%l0, %o0, %l1 srlx%l1, 32, %l0 brnz,a%l0, fact05 clr%o0 mov%l1, %o0 fact05: ldx[%sp ], %l1 inc8, %sp ldx[%sp ], %l0 inc8, %sp ldx[%sp ], %o1 inc8, %sp ldx[%sp ], %o7 inc8, %sp retl nop %o7 %o1 %l0 %l1 %sp %sp-8 %sp-16 %sp-24 %sp-32
La pile sous Solaris Espace d’adressage d’un processus 18 0xFFFFFFFFFFFFFFFF 0x Pile Biais %sp %sp+0x7FF 2047 Système Pile Librairies partagées Tas (heap) Données Instructions Système section.text section.data,.rodata,.bss
La pile sous Solaris Le contenu de la pile varie selon l’utilisation que le programmeur veut en faire Si le programmeur utilise l’instruction save Le système d’exploitation utilise aussi la pile Si un sous-programme en assembleur est appelé par un programme en langage évolué (par exemple C) Le code généré par le compilateur modifie le contenu de la pile Il faut donc respecter certaines règles d’utilisation 19
La pile sous Solaris Pour résoudre le manque de fenêtres de registres, le programme et les sous-programmes s’allouent un espace sur la pile Appelé « bloc » C’est le système d’exploitation qui s’occupe de sauvegarder dans un bloc l’image de tous les registres de la fenêtre utilisée 20
La pile sous Solaris Allocation d’un bloc 21 save %sp, -nn, %sp save %sp, -mm, %sp restore %sp %fp %sp %fp
La pile sous Solaris Composition d’un bloc 22 Registres %i0 à %i7 %l0 à %l7 %sp Registres %o0 à %o5 Paramètres additionnels Espace de travail Données dynamiques Données locales -128 octets -48 octets -q octets -p octets -n octets -m octets %fp Tout programme a accès aux données de son bloc Grâce au registre %sp, avec des déplacements positifs Grâce au registre %fp, avec des déplacements négatifs Tout programme a accès aux données du bloc de l’appelant Grâce au registre %fp avec des déplacements positifs Tout bloc doit être aligné sur une frontière de double mot Le 128 ajouté à la valeur du %sp dans les exemples précédents