IN 103 - Cours 7 1 Piles

publicité
IN 103 - Cours 7
1
Piles
Une pile est une structure de données permettant de stocker des éléments d’un même type.
Une pile d’entiers permettra de stocker des entiers, une pile de
stocker des struct blah t .
Une pile est une structure
struct blah t permettra de
dernier entré-premier sorti .
push : on empile (rajoute) une information sur le sommet de la pile.
pop : on dépile (retire) l’information se trouvant au sommet de la pile.
push (stack, elem4)
1)
elem4
2)
elem4
pop (stack)
elem3
pop (stack)
elem4
elem3
elem3
elem2
elem2
elem1
elem2
elem1
elem1
En C on représente l’espace de stockage d’une pile par un tableau.
Pour savoir où empiler et d’où dépiler, on mémorise un pointeur de pile indique la prochaine
place libre dans le tableau.
Le pointeur de pile n’est pas un pointeur C : c’est un entier positif représentant un indice
dans le tableau de la pile.
En C, une pile de taille fixe (64) contenant des éléments de type
par une structure :
un type est représentée
#define MAX SIZE 64
struct s t a c k {
unsigned i n t sp ;
/∗ P o i n t e u r de p i l e . ∗/
u n t y p e data [ MAX SIZE ] ;
/∗ Zone de s t o c k a g e de l a p i l e . ∗/
};
Initialement, une pile est vide (ne contient pas d’éléments) : le
pointeur de pile est à 0.
Essayer de dépiler dans une pile vide ( pointeur de pile == 0) provoque une erreur.
Essayer d’empiler dans une pile pleine ( pointeur de pile == MAX SIZE) provoque une erreur.
???
sp
data[MAX_SIZE − 1]
???
???
data[2]
???
???
data[1]
5
42
data[0]
42
1
sp
2
sp
push (stack, 5) :
— Vérifier que sp < M AX SIZE
— 5 mis à l’indice sp ⇒ 1
— Incrémenter sp : sp ← sp + 1 ⇒ 2
push (stack, 5)
1
???
data[MAX_SIZE − 1]
???
5pop
sp
???
data[2]
???
5
data[1]
?5?
42
data[0]
42
2
sp
1
(stack)
— Vérifier que sp > 0
— Décrémenter sp : sp ← sp−1 ⇒ 1
— Retourner la valeur à l’indice sp
(sommet de la pile)
sp
pop (stack)
On peut implanter une pile de taille non fixe en allouant dynamiquement (avec malloc) le
tableau et en le ré-allouant (nouvelle allocation, recopie, libération de l’ancien tableau) lorsque
la pile est pleine.
2
Du code source à l’exécution
Code source = description statique.
Exécutable = comportement dynamique.
Le langage dans lequel est écrit le source possède une sémantique dynamique.
Processus du code source à l’exécution :
1. Découpe du source en
mots et vérification de bonne orthographe : analyse lexicale.
2. Assemblage des mots en
taxique.
phrases et vérification de bonne grammaire : analyse syn-
3. Analyses sémantiques et vérification du
sens correct des phrases.
4. Production de code assembleur et optimisation.
5. Production de code binaire : assemblage.
6. Regroupement final de tous les composants : édition de lien.
7. Chargement en mémoire puis exécution.
3
Exécution (mono-tâche et simplifiée)
Un CPU possède quelques zones de stockage internes rapides : les registres.
Un CPU ne comprend que des instructions élémentaires : déplacement de données, arithmétique,
logique, saut, (+ quelques autres).
Cycle infini du CPU : récupérer l’instruction courante, la décoder, l’exécuter, passer à l’instruction suivante.
Adresse de l’instruction courante : dans un registre dédié
PC .
Pour effectuer des saut conditionnels, il est nécessaire de mémoriser le statut des conditions
testées : un registre dédié SR avec 1 bit par condition (résultat nul, positif, négatif, débordement
. . . ).
Pour les appels de fonctions et les variables locales, il faut une pile d’exécution. Adresse du
pointeur de pile : dans un registre dédié SP .
Charger un code en mémoire c’est recalculer les adresses figurant dans ses instructions en fonction de là où il a été logé.
Lancer un code chargé en mémoire lui attribuer une zone de pile (initialiser SP), effacer les bits
de conditions (SR) et mettre le PC à l’adresse de début de ce code.
C’est un des rôles du système d’exploitation (OS) de charger et lancer l’exécution.
2
Téléchargement