Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres.
Il s'agit d'un moyen d'accéder à des données en les empilant, telle une pile
de livres, puis en les dépilant pour les utiliser. Ainsi il est nécessaire de dépiler
les valeurs stockées au sommet (les dernières à avoir été stockées)
pour pouvoir accéder aux valeurs situées à la base de la pile.
En réalité il s'agit d'une zone de mémoire et d'un pointeur qui permet de repérer
le sommet de la pile.
La pile est de type LIFO (Last In First Out), c'est-à-dire que la première valeur empilée
sera la dernière sortie (Si vous empilez des livres, il vous faudra les dépiler en commençant
par enlever les livres du dessus. Le premier livre empilé sera donc le dernier sorti!).
Les instructions PUSH et POP sont les instructions qui servent à empiler et dépiler
les données.
PUSH registre
met le contenu du registre dans la pile (empilement)
POP registre
récupère le contenu de la pile et le stocke dans le registre (dépilage)
Ainsi, l'instruction PUSH BX empile le contenu du registre BX, et l'instruction POP AX
récupère le contenu du sommet de la pile et le transfère dans AX.
Dans l'exemple suivant, que l'on imaginera au milieu d'un programme, on stocke les valeurs
contenues dans AX et BX pour pouvoir utiliser ces deux registres, puis une fois l'opération
accomplie on remet les valeurs qu'ils contenaient précédemment...
PUSH AX
PUSH BX
MOV AX, [0140]
ADD BX, AX
MOV [0140], BX
POP BX
POP AX
Les registres SS et SP sont deux registres servant à gérer la pile:
- SS (Stack Segment, dont la traduction est segment de pile) est un registre 16 bits contenant
l'adresse du segment de pile courant. Il doit être initialisé au début du programme
- SP (Stack Pointer, littéralement pointeur de pile) est le déplacement pour atteindre
le sommet de la pile (16 bits de poids faible)
SP pointe vers le sommet, c'est-à-dire sur le dernier bloc occupé de la pile.
Lorsque l'on ajoute un élément à la pile, l'adresse contenue dans SP est
décrémentée de 2 octets (car un emplacement de la pile fait 16 bits de longueur).
En effet, lorsque l'on parcourt la pile de la base vers le sommet, les adresse décroissent.
Par contre l'instruction POP inccrémente de 2 octets (16 bits) la valeur de SP.
- PUSH: SP <- SP - 2
- POP: SP <- SP + 2
Ainsi, lorsque la pile est vide SP pointe sous la pile (la case mémoire en-dessous de la base de la pile)
car il n'y a pas de case occupée.
Un POP provoquera alors une erreur...
Pour pouvoir utiliser une pile, il faut la déclarer, c'est-à-dire réserver
un espace mémoire pour son utilisation, puis initialiser les registres avec les valeurs
correspondant à la base de la pile, ainsi que son sommet (rappel: situé sous la
pile lorsque celle-ci est vide).
Ainsi pour définir une pile il s'agit tout d'abord de la déclarer grâce
à la directive SEGMENT stack.
Suite aux déclarations, il faut écrire une séquence d'initialisation :
ASSUME SS:segment_pile
MOV AX, segment_pile
MOV SS, AX ; initialise le segment de pile
MOV SP, base_pile ; copier l'adresse de la base de la pile dans SP
Il n'est pas possible de faire directement MOV SS, segment_pile car cette instruction n'existe pas!
|