Logiciel de base Première année ENSIMAG 1
Procédures, paramètres, pile En assembleur une fonction est une étiquette, c'est l'adresse de sa première instruction Lors de l'appel d'une fonction, la pile sert à stocker les paramètres 2
Motivations Réfléchir à la mise en œuvre en assembleur de la notion de procédure ou de fonction qui est l unité de structuration de base d un programme. Définir les différentes conventions de liaison à respecter sous Unix si on veut pouvoir importer (resp. exporter) dans un programme assembleur (resp dans un programme C ou Pascal) des fonctions ou des procédures écrites dans un autre langages (C, Pascal ou l assembleur) 3
Mise en œuvre de la notion de procédure ou de fonction Appel : call <etiquette> Retour : instruction ret 4
Mécanisme de passage de contrôle (1) Le problème : Programme fonction principal La fonction appelée doit pouvoir rendre le contrôle à l instruction suivant celle de l appel : adresse de retour à une adresse fixe Non adresse de retour associée à la fonction Non adresse de retour gérée en pile Oui 5
Mécanisme de passage de contrôle (2) Gestion du mécanisme sur le 80X86 Appel CALL : ESP Avant call ESP Après call @ retour Adresse mémoire décroissante 2 octets 2 octets Zone déjà utilisée Zone de mémoire libre 6
Mécanisme de passage de contrôle (3) Gestion du mécanisme sur le 80X86 Retour RET : ESP Avant ret Après ret @ retour ESP Adresse mémoire décroissante 2 octets Zone occupée 2 octets Zone libre 7
Contexte d exécution d une procédure Définition : On entendra par contexte d exécution de la procédure l ensemble des variables auxquelles elle a accès. Ses variables locales Les variables globales (publiques ou privées) Ses paramètres d appel Les registres de la machine qui peuvent servir à implanter l une des catégories de variables utilisables par une procédure. 8
Gestion des variables locales (1) le principal problème à résoudre est de permettre les différents cas de récursivité et d assurer l allocation et la libération automatique des variables locales à l entrée et à la sortie d une f: f: procédure f: g: f: f: 9
Gestion des variables locales (2) Solution : Elle sont allouées sur la pile à l entrée dans la procédure et libérées à la sortie Pour faire cela il suffit de retrancher (resp. ajouter) à ESP le plus petit entier pair supérieur à la taille totale en octet des variables locales Entrée dans f ESP Après SUBL $TVAR_LOC, % ESP Après ADDL $TVAR_LOC,% ESP TVAR_LOC Variables locales ESP Adresse de retour Adresse de retour 2 octets ESP Adresse de retour 10
Adressage des variables locales (1) Problème Désignation des variables locales indépendamment du contexte d exécution de la fonction => Pas d'adressage relatif au pointeur de pile, => Pas d adressage absolu. Solution Adressage des variables locales relativement à un registre de base différent du pointeur de pile. Mais ce registre doit être sauvé à l entrée de la fonction et restauré avant de rendre le contrôle à l appelant. 11
Adressage des variables locales (2) ESP Etat de la pile à l entrée et à la sortie de f avant d exécuter RET Adresse de retour ESP XX EBP Variables locales XX EBP appelant Adresse de retour f: PUSHL %EBP MOVL %ESP, %EBP # Variables locales SUBL $TVAR_LOC,%ESP ---- MOVL XX(%EBP),%EAX ---- # Restoration de la pile : MOVL %EBP,%ESP POPL %EBP RET 12
Gestion des registres (1) Problème : Registre = variable globale movl $4, %eax call f movl %eax,... # utilise %eax Par l appelant préalablement à l appel : Restauration faite au retour, chez l appelant Par l appelé : Restauration avant le retour, chez l appelé 13
Gestion des registres (2) Exemple du 80X86 : ESP EBP Sauvegarde des registres Variables locales EBP appelant -TVAR_LOC # Allocation sur la pile f: ENTER $TVAR_LOC, $0 PUSHAL ---- # Restoration POPAL LEAVE RET Adresse de retour 14
Gestion des registres (3) Sauvegarde par l'appelant/appelé : Que choisir? Il faut que l'appelant et l'appelé aient la même convention! On peut avoir une convention différente par registre : Registres Scratch => l'appelé n'est pas tenu de sauvegarder. L'appelant sauvegarde si besoin. Registres non volatiles => l'appelé doit sauvegarder les registres dont il se sert. 15
Gestion des paramètres Paramètres par valeur ou par référence Les paramètres d une fonction peuvent être définis par leur valeur ou par leur adresse ou référence en mémoire : Valeur : c est directement une valeur du type défini pour le paramètre formel qui est fournie à l appel de la fonction. Ce mode est réservé pour les variables de type simple ( entier, caractère ) Adresse : c est l adresse de la variable en mémoire qui est fournie à la procédure lors de l appel, sur 4 octets. 16
Mode de passage des paramètres Passage par registres Pour un petit nombre de paramètres de type simple passés par valeur ou de type complexe passés par adresse c est le mode le plus efficace. Des conventions entre appelant et appelé définissent l utilisation des registres. Passage des paramètres sur la pile L appelant recopie, avant l appel, dans la pile soit la valeur des paramètres d appel soit leur adresse. Au retour il libère la place occupée par les paramètres. 17
Adressage des paramètres (1) Si les paramètres sont passés par registres les paramètres sont désignés par le nom du registre qui contient leur valeur, ou basé par le registre qui contient leur adresse. S ils sont passés dans la pile ils sont adressés, comme les variables locales, au moyen de leur déplacement relativement à EBP. 18
Adressage des paramètres ESP(2) EBP Pi Sauvegarde des registres Variables locales EBP appelant Adresse de retour Pi paramètres P1 -TVAR_LOC # Préparation et appel de la fonction f # Passage par référence : basée par %eax --- PUSHL Pi(%EBP) --- LEA Pi(%EBP), %EAX PUSHL %EAX CALL f 19
Conventions de liaisons (1) Définition On appelle convention de liaison (Application Binary Interface ou ABI) les conventions de programmation imposées par le système aux applications qui l utilisent. Ces conventions peuvent imposer : un certain nombre d appels au système et la façon de les réaliser les adresses mémoires utilisables par un programme des conventions d utilisation des registres 20
Conventions de liaisons Linux Le format d un bloc de pile associé à un appel est conforme à ce que nous avons présenté. La libération des paramètres est faite par l appelant et pas par l appelé Les paramètres d une procédure sont empilés de la droite vers la gauche f( p1, p2,, pn ) on empile d abord pn.on empile toujours un nombre pair d octets et au moins 4 (32 bits) Paramètre par référence : adresse de la variable effective sur 4 octets Paramètre par valeur, de type simple (entier, pointeur) : on empile la valeur effective sur 4 octets. 21
Registres et conventions de liaison Unix %ebp, %ebx, %edi, %esi, et %esp : registres non-volatiles. => On sauvegarde si on utilise Les autres (%eax, %ecx, %edx,...) sont scratch. => On fait ce qu'on veut avec, mais un call peut les modifier %eax contient le résultat d une fonction. 22
Entrées Sorties Impression d une chaîne msg:.string "ceci est une chaine\n" pushl $msg # Chaine => adresse call printf # Appel printf addl $4,%esp # Restauration par # l'appelant 23
Affichage de la valeur d une variable f:.string "la valeur de i est : %d\n " i:.int 4231 pushl i # 4 octets par valeur pushl $f # 4 octets call printf # Appel printf addl $8,%esp # Restaure 4 + 4 24
Lecture au clavier fe:.string "%d" i :.int 0 pushl $i # Par référence pushl $fe # Chaine call scanf # Appel scanf addl $8,%esp # Restauration 25