Environnements d'exécution

Slides:



Advertisements
Présentations similaires
La programmation orientée objet avec Java L3-MIAGE Plan
Advertisements

Premier programme en C :
Rappels C.
Algorithmes et structures de données 9ème cours Patrick Reuter maître de conférences
Sensibilisation à l’Algorithmique et structure de données
3- Déclaration et accès aux objets
La pile un élément essentiel
C.
Les structures de données
Structures et unions types énumérés Qu'est-ce qu'une structure
Les pointeurs Manipulation d'adresses et de ce qui est contenu dans ces adresses Très important, fondamental même en C mauvaise réputation : 'dur à comprendre',
Introduction : Compilation et Traduction
FLSI602 Génie Informatique et Réseaux
Les sous-programmes Chapitre n° 5: Objectifs : Activité:
Principes de programmation (suite)
Regrouper des éléments de même type et pouvoir y accéder à laide dun identificateur et dun indice. Objectif des tableaux.
Sous-programmes Concepts généraux Passage de paramètres Fonctions
Structures de données linéaires
Récursivité.
CSI3525: Concepts des Langages de Programmation Notes # 12: Implementation des Sous-Programmes ( Lire Chapitre 9 )
TP : Fichiers et Tableaux Séance N°2 Avril Application de Gestion de stock Partie 1 : les fichiers 1 Création dun fichier de 20 articles.
TP Fichiers et Tableaux Avril Un fichier Permet le stockage de données sur des supports de mémoire externes (donc les données ne seront pas perdues.
Introduction au paradigme objet Concepts importants surcharge (overload) redéfinition (override) Définition d’une classe Définition des attributs.
Les Classes les structures en C (struct) regroupent des variables : structuration de l'analyse mais problèmes de cohérence problèmes de sécurité d'accès.
Quest-ce quune classe dallocation? Une classe dallocation détermine la portée et la durée de vie dun objet ou dune fonction.
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
Contrôle de types Les types en programmation Expressions de types Un contrôleur de types Equivalence de types Conversions de types Généricité.
Architecture et technologie des ordinateurs II
IFT 6800 Atelier en Technologies d’information
LIFI-Java 2004 Séance du Jeudi 9 sept. Cours 1. La notion de langage Décrire une tâche à effectuer –programme Écrire à un haut niveau –facile pour lutilisateur.
Chapitre 9 Les sous-programmes.
8PRO100 Éléments de programmation Les types composés.
1-1 Chapitre 5: Les variables Introduction Les noms Les variables Les attributions (bindings) Portée et durée de vie L'environnement de référence Les noms.
Méthode et Outils pour la Programmation
Leçon 1 : notion dobjet IUP Génie Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
Procédures et fonctions
Plan cours La notion de pointeur et d’adresse mémoire.
Structures des données
2.1 - Historique Chapitre 2 : Introduction au langage C++
Le langage C Rappel Pointeurs & Allocation de mémoire.
JavaScript Nécessaire Web.
Cours Architecture des Systèmes Informatiques
Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques
O-notation 1. Introduction 2. O-notation 3. Opérations 3.1 Somme 3.2 Produit 4. Règles générales 5. Exemple 6.Analyse des algorithmes récursifs 6.1 Dilatation.
La notion de type revisitée en POO
Les adresses des fonctions
SIF-1053 Architecture des ordinateurs
Créer des packages.
Un survol du language C.
1 Structures des données. 2  Le tableau permettait de désigner sous un seul nom un ensemble de valeurs de même type, chacune d'entre elles étant repérée.
Master 1 SIGLIS Java Lecteur Stéphane Tallard Les erreurs communes en Java.
Tutorat en bio-informatique
Tutorat en bio-informatique Le 14 novembre Au programme… Les objets –Propriétés (attributs) –Constructeurs –Méthodes.
Introduction au langage C Fonctions et Procédures
CSI 3525, Implémentation des sous-programmes, page 1 Implémentation des sous-programmes L’environnement dans les langages structurés en bloc La structure.
1 École des Mines de Saint-Etienne. 158, cours Fauriel Saint-Etienne Cedex 2. Tél Fax Jean-Jacques Girardot
ISBN Chapitre 10 L'implémentation des sous- programmes.
Cours LCS N°4 Présenté par Mr: LALLALI
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
Cours 4 (14 octobre) Héritage. Chapitre III Héritage.
Initiation au JavaScript
6ième Classe (Mercredi, 17 novembre) CSI2572
Conception de Programmes - IUT de Paris - 1ère année Quelques éléments du langage C++ Les références La surcharge de fonctions Les fonctions «
CPI/BTS 2 Algorithmique & Programmation La récursivité Algo – Prog CPI/BTS2 – M. Dravet – 14/09/2003 Dernière modification: 14/09/2003.
Langage de programmation
1 Cours 6 Définitions de nouvelles procédures Transmissions de données/résultats Déclarations globales/locales Visibilités Interface/implementation.
Organisation de la mémoire pour le langage minimal Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)
Transcription de la présentation:

Environnements d'exécution Notions de base Spécificités des langages sources Organisation de la mémoire Stratégies d'allocation mémoire Accès aux noms non locaux Passage de paramètres

Objectifs Décrire la relation entre le programme source et l'exécution Exemple de notion statique : les noms des variables (font partie du programme source) Exemple de notion dynamique : les adresses des variables (existent pendant l'exécution) Décrire le moteur d'exécution Le code que le système d'exploitation lance pour exécuter le programme compilé Langages C, Java, Pascal, Lisp, Fortran

Notions de base (1/2) Procédures ou fonctions Définies par l'association d'un identificateur, le nom, et d'une instruction, le corps Parfois on dit fonction quand elle renvoie une valeur et procédure sinon ; nous ne ferons pas la différence Paramètres formels Dans la définition de la fonction Paramètres effectifs Dans un appel de la fonction Activation d'une fonction Période qui va de l'appel d'une fonction (avec éventuellement des paramètres réels) à son retour

Exemple program sort(input, output) ; var a : array[0..10] of integer ; procedure readarray ; var i : integer ; begin for i := 1 to 9 do read(a[i]) end ; function partition(y, z : integer) : integer ; begin ... end ; procedure quicksort(m, n : integer) ; begin if (n>m) then begin i := partition (m, n) ; quicksort(m, i - 1) ; quicksort (i + 1, n)

Exemple end end ; begin a[0] := - 9999 ; a[10] := 9999 ; readarray ; quicksort(1, 9) end.

Notions de base (2/2) Fonctions récursives Fonction dont une activation peut commencer alors qu'une autre est en cours Arbre d'exécution Les noeuds sont les activations des fonctions avec leurs paramètres Chaque fils d'un noeud correspond à un appel Pile d'exécution La pile des activations en cours à un instant donné Portée d'une déclaration Noms locaux, noms globaux

Arbre d'exécution sort quicksort(1, 9) readarray partition(1, 9)

Pile d'exécution ... ... sort quicksort(1, 9) readarray partition(1, 9) quicksort(1, 3) quicksort(5, 9) partition(1,3) partition(5, 9) quicksort(1, 0) quicksort(5, 5) ... ... sort quicksort(1, 9) quicksort(1, 3) fond de pile sommet de pile

Notions statiques et dynamiques Exemple : passage d'un nom de variable à une valeur liaison état nom adresse valeur Si l'environnement associe une occurrence du nom x à l'adresse s, on dit que x est lié à s Un nom peut être lié à plusieurs adresses Une occurrence d'un nom peut être liée à plusieurs adresses (fonction récursive) Une adresse peut contenir plusieurs valeurs successivement

Notions statiques et dynamiques statique dynamique connu à la compilation dépend de chaque exécution définition d'une fonction activations d'une fonction déclaration d'un nom liaisons d'un nom portée d'une déclaration durée de vie d'une liaison

Spécificités des langages L'organisation d'un compilateur dépend des réponses à des questions sur le langage source Y a-t-il des fonctions récursives ? Comment sont traités les noms locaux au retour des fonctions ? Une fonction peut-elle utiliser des noms non locaux ? Comment sont passés les paramètres ? Les fonctions peuvent-elles être passées en paramètre ? être renvoyées comme valeur ? L'allocation de mémoire peut-elle être dynamique ? La libération doit-elle être explicite ?

Organisation de la mémoire Zone utilisée en mémoire pour l'exécution d'un programme Code exécutable (taille statique) Données statiques : dont les adresses sont compilées dans le code Pile d'exécution Le tas est l'emplacement de toutes les autres informations : en C, la mémoire allouée dynamiquement Les adresses dans la pile sont des adresses relatives (offset) par rapport au sommet de la pile code données statiques pile tas

Enregistrements d'activation Zone de mémoire empilée à l'appel d'une fonction et dépilée au retour fond de pile Lien de contrôle : pointe sur l'enregistrement d'activation appelant Lien d'accès : accès aux variables non locales Etat machine : valeurs des registres au moment de l'appel Zone temporaire : pour le calcul des expressions valeur renvoyée paramètres effectifs lien de contrôle lien d'accès (en Pascal) sauvegarde de l'état de la machine variables locales zone temporaire sommet de pile

Disposition des données locales Adresses calculées à la compilation Unité minimale d'adressage L'octet (byte) Pour certaines opérations : le mot machine, souvent 4 octets Espace laissé vide : remplissage (padding) Placement d'un objet Octets consécutifs (la taille dépend du type) L'adresse est celle du premier octet Pendant l'analyse des déclarations Adresses relatives Par rapport à un point de référence dans l'enregistrement d'activation

Exemple La taille de chaque type C dépend de la machine machine type char short int long float taille (bits) 8 16 32 alignement (bits) taille 24 48 64 alignement 1 2 Alignement : sur la machine 1, si un char est suivi d'un short, on perd 1 octet Taille d'un pointeur : sur la machine 2, 24 bits pour le mot et 6 pour 1 bit parmi 64, donc 30 bits

Allocation statique La stratégie d'allocation mémoire la plus simple Toutes les liaisons sont permanentes pendant toute l'exécution Les valeurs des noms locaux persistent d'un appel au suivant Les adresses des données sont statiques L'emplacement des enregistrements d'activation est statique Limitations La taille de toutes les données est statique La récursivité est interdite La création dynamique de structures de données est interdite

Exemple Un programme en Fortran qui - lit une ligne et la copie dans un tampon BUFFER - copie BUFFER dans BUF jusqu'à rencontrer un espace, puis affiche BUF (programme principal) Exemple entrée : demain matin sortie : demain La fonction PRDUCE - lit la ligne et la copie dans BUFFER (premier appel) - puis lit dans BUFFER un caractère par appel Le programme principal écrit dans BUF puis affiche BUF Attention au choc culturel...

Exemple PROGRAM CNSUME CHARACTER * 50 BUF INTEGER NEXT CHARACTER C, PRDUCE DATA NEXT /1/, BUF /' '/ 6 C = PRDUCE() BUF(NEXT:NEXT) = C NEXT = NEXT + 1 IF ( C .NE. ' ' ) GOTO 6 WRITE (*, '(A)') BUF END

CHARACTER FUNCTION PRDUCE() CHARACTER * 80 BUFFER INTEGER NEXT SAVE BUFFER, NEXT DATA NEXT /81/ IF ( NEXT .GT. 80 ) THEN READ (*, '(A)') BUFFER NEXT = 1 END IF PRDUCE = BUFFER(NEXT:NEXT) NEXT = NEXT+1 END

L'instruction SAVE permet à PRDUCE de retrouver les valeurs de BUFFER et NEXT d'un appel à l'autre code de CNSUME code de PRDUCE enregistrement d'activation de CNSUME : BUF NEXT C enregistrement d'activation de PRDUCE : BUFFER code données statiques

Allocation en pile Les enregistrements d'activation sont empilés à l'appel de la fonction et dépilés au retour Les valeurs locales sont perdues Séquence d'appel réserve et remplit un enregistrement d'activation Séquence de retour restaure l'état de la machine avant l'appel pour reprendre l'exécution où elle en était

sauvegarde de l'état machine données locales temporaires valeur renvoyée paramètres lien d'accès sauvegarde de l'état machine données locales temporaires enregistrement d'activation de l'appelant lien de contrôle à la charge de l'appelant valeur renvoyée paramètres lien d'accès sauvegarde de l'état machine données locales temporaires enregistrement d'activation de l'appelé lien de contrôle sommet de pile

Séquences d'appel et de retour Séquence d'appel L'appelant évalue les paramètres Il enregistre l'adresse de retour et la valeur du sommet de pile dans l'enregistrement d'activation de l'appelé Il incrémente le sommet de pile L'appelé sauvegarde les valeurs des registres Il initialise ses données locales Séquence de retour L'appelé place la valeur à renvoyer Il restaure le sommet de pile et les autres registres et saute à l'adresse de retour L'appelant copie la valeur renvoyée

Allocation en pile Données de taille variable Les données de taille variable sont placées sur la pile au-dessus de l'enregistrement d'activation Leur adresse relative n'est pas connue à la compilation L'enregistrement d'activation contient des pointeurs vers ces données Les adresses relatives de ces pointeurs sont connues à la compilation On utilise un 2e pointeur de sommet de pile qui tient compte des données de taille variable (sommet)

sauvegarde de l'état machine lien d'accès sauvegarde de l'état machine lien de contrôle enregistrement d'activation de p pointeur sur A pointeur sur B tableau A tableaux de p tableau B lien d'accès sauvegarde de l'état machine données locales temporaires lien de contrôle enregistrement d'activation de q sommet de pile tableau A tableaux de q sommet

Allocation en pile Données de taille variable Au retour de q, la nouvelle valeur de Sommet est restaurée à partir de SommetPile en tenant compte de la taille des champs de sauvegarde, liens, paramètres et valeur de retour la nouvelle valeur de SommetPile est la valeur du lien de contrôle

Accès aux noms non locaux Dépend des règles de portée des variables dans le langage source Les règles qui relient les occurrences des variables à leurs déclarations Portée statique ou lexicale C, Java, Pascal, Ada Portée déterminée par le texte source du programme Portée dynamique Lisp, APL, Snobol Portée déterminée par les activations en cours

Structure de blocs Bloc --> { Déclarations Instructions } Les instructions peuvent contenir des blocs Une fonction peut contenir plusieurs blocs Portée statique La portée d'une déclaration faite dans B est incluse dans B Si un nom x n'est pas déclaré dans B (non local à B), une occurrence de x dans B est liée à la déclaration de x dans le plus petit bloc B' tel que - x est déclaré dans B' - B' contient B

Exemple B0 B1 B2 B3 main() { int a = 0 ; int b = 0 ; int b = 1 ; printf("%d %d", a, b) ; } int b = 3 ; B0 B1 B2 B3

Portée statique Réalisation : deux méthodes Allocation en pile On considère chaque bloc comme une fonction sans paramètres ni valeur de retour Allocation globale On regroupe toutes les variables déclarées dans les blocs de la fonction On peut lier à une même adresse deux variables dont les portées sont disjointes (a de B2 et b de B3)

Portée statique sans fonctions emboîtées Les noms sont de deux sortes : - locaux à une fonction - globaux, déclarés hors des fonctions Exemple : le langage C Les noms globaux sont alloués de façon statique Les noms locaux sont en pile, accessibles à partir du pointeur de sommet de pile Pas besoin de lien d'accès

Fonctions passées en paramètre Avec la portée statique sans fonctions emboîtées, on peut facilement passer une fonction en paramètre ou la renvoyer comme résultat #include <stdio.h> int m ; int f(int n) { return m + n ; } int g(int n) { return m * n ; } int b(int (*h)(int)) { printf("%\n", h(2)) ; } int main(void) { m = 0 ; b(f) ; b(g) ; }

Portée statique avec fonctions emboîtées (1/6) En Pascal, on peut déclarer une fonction à l'intérieur d'une autre Les emboîtements de fonctions forment un arbre statique sort readarray exchange(i, j) quicksort(m, n) Profondeur d'emboîtement 1 pour le programme principal On ajoute 1 pour chaque imbrication

Exemple program sort(input, output) ; var a : array[0..10] of integer ; x : integer ; procedure readarray ; var i : integer ; begin for i := 1 to 9 do read(a[i]) end ; procedure exchange(i, j : integer) ; begin x := a[i] ; a[i] := a[j] ; a[j] := x end ; procedure quicksort(m, n : integer) ; var k, v : integer ; function partition(y, z : integer) : integer ; var i, j : integer ; begin ... a ... v ... exchange(i, j) ; ... end ; begin ... end ; begin ... end .

Portée statique avec fonctions emboîtées (2/6) sort quicksort(m, n) readarray exchange(i, j) partition(y, z) Profondeur d'une variable Profondeur d'emboîtement de la fonction où elle est définie Une variable de profondeur v ne peut être utilisée que dans une fonction de profondeur f  v Une fonction de profondeur g ne peut être appelée que par une fonction de profondeur f  g - 1 ; f = g - 1 seulement si g est locale à f

Portée statique avec fonctions emboîtées (3/6) sort quicksort(m, n) readarray exchange(i, j) partition(y, z) Si une fonction g locale à f a un enregistrement d'activation dans la pile, alors f a un enregistrement d'activation au-dessous de celui de g (c'est l'EA le plus récent qui soit de profondeur inférieure à celle de g) L'enregistrement d'activation de f n'est pas forcément juste au-dessous de celui de g Le lien de l'EA de g vers l'EA de f est le lien d'accès

Portée statique avec fonctions emboîtées (4/6) sort quicksort(m, n) readarray exchange(i, j) partition(y, z) Si une variable est utilisée dans une fonction g, - elle est déclarée dans g ou dans une fonction h qui contient g - on la lie à un enregistrement d'activation présent dans la pile : l'enregistrement d'activation de h le plus récent - on accède à cet EA en remontant les liens d'accès - le nombre de liens d'accès est la différence de profondeur entre g et h

Portée statique avec fonctions emboîtées (5/6) sort quicksort(m, n) readarray exchange(i, j) partition(y, z) Si une variable a de profondeur p(a) est utilisée dans une fonction f de profondeur p(f), on trouve son adresse : - en remontant p(f) - p(a) liens d'accès - en utilisant l'adresse relative de a dans l'enregistrement d'activation obtenu Ces deux valeurs sont connues à la compilation Elles représentent la liaison de cette occurrence de a

Portée statique avec fonctions emboîtées (6/6) Calcul du lien d'accès dans la séquence d'appel Une fonction f appelle une fonction g Si p(f) = p(g) - 1 g est locale à f : le lien d'accès est égal au lien de contrôle Si p(f)  p(g) on remonte p(f) - p(g) + 1 liens d'accès depuis l'enregistrement d'activation de f Ces calculs sont faits à la compilation

sort a, x sort a, x sort a, x sort a, x quicksort(1, 9) k, v quicksort(1, 9) k, v quicksort(1, 9) k, v quicksort(1, 9) k, v accès accès accès accès quicksort(1, 3) k, v quicksort(1, 3) k, v quicksort(1, 3) k, v accès accès accès partition(1, 3) i, j partition(1, 3) i, j accès accès exchange(1, 3) accès

Fonctions passées en paramètre program param(input, output) ; procedure b(function h(n : integer) : integer ; begin writeln(h(2)) end ; procedure c ; var m : integer ; function f(n : integer) : integer ; begin f := m + n end ; begin m := 0 ; b(f) end ; begin c end .

Fonctions passées en paramètre Calcul du lien d'accès à l'appel de f param c m accès b <f ; > k, v acc Pour appeler f on a besoin de l'adresse du code et du lien d'accès accès

Accès direct aux noms non locaux Une méthode plus rapide pour accéder aux noms non locaux Un tableau de pointeurs vers les enregistrements d'activation Pour chaque profondeur j, display[j] pointe vers l'enregistrement d'activation où sont placés les noms non locaux de niveau j A chaque appel on met à jour display Quand on empile un enregistrement de profondeur i, 1. sauvegarder display[i] dans le nouvel enregistrement 2. faire pointer display[i] sur le nouvel enregistrement Avant de dépiler, on restaure display[i]

sort sort sort sort d[1] d[1] d[1] d[1] d[2] d[2] d[2] d[2] qs(1, 9) qs(1, 9) qs(1, 9) qs(1, 9) d[2] d[2] d[2] d[2] d[3] d[3] qs(1, 3) qs(1, 3) qs(1, 3) d[2] d[2] d[2] pt(1, 3) pt(1, 3) d[3] d[3] ex(1, 3) d[2]

Portée dynamique Les liaisons des noms non locaux ne changent pas quand on appelle une fonction Un nom non local dans la fonction appelée est lié au même emplacement que dans la fonction appelante Réalisation On recherche l'emplacement des noms non locaux en suivant les liens de contrôle On n'a pas besoin de liens d'accès

Portée dynamique Résultats : portée statique 0.250 0.250 program dynamic(input, output) var r : real ; procedure show begin write(r : 5:3) end ; procedure small begin r := 0.125 ; show end ; begin r := 0.250 ; show ; small ; writeln ; end . Résultats : portée statique 0.250 0.250 portée dynamique 0.250 0.125

Passage des paramètres (1/5) Passage par valeur Les valeurs des paramètres effectifs sont passés à la procédure appelée Exemple : le langage C Réalisation Les paramètres formels sont traités comme des noms locaux Les paramètres effectifs sont évalués par l'appelant Ne modifie pas les valeurs dans l'enregistrement d'activation de l'appelant, sauf à travers des noms non locaux ou des pointeurs passés par valeur

Passage des paramètres (2/5) Pascal procedure echange(i, j : integer) ; var x : integer ; begin x := a[i] ; a[i] := a[j] ; a[j] := x end C swap(int * x, * y) { int temp ; temp = * x ; * x = * y ; * y = temp ; } main() int a = 1, b = 2 ; swap(& a, &b) ;

Passage des paramètres (3/5) Passage par référence Les adresses des paramètres effectifs sont passés à la procédure appelée Exemple en Pascal program reference(input, output) ; var a, b : integer ; procedure swap(var x, y : integer) ; var temp : integer ; begin temp := x ; x := y ; y := temp end ; a := 1 ; b := 2 ; swap(a, b) ; end .

Passage des paramètres (4/5) Passage par copie et restauration Les valeurs des paramètres effectifs sont passées à la procédure appelée Au retour, les nouvelles valeurs des paramètres sont copiées à leur adresse Exemple : Fortran

Passage des paramètres (5/5) Passage par nom Le corps de la fonction est substitué à l'appel Les paramètres sont substitués littéralement Exemples Algol Macros en C #define swapint(a, b) {int x = a ; a = b ; b = x ; } swapint(i, a[i]) affecte la valeur i à a[a[i]]