Les procédures du BIOS
Il y a des actions qui reviennent souvent, comme écrire à l'écran par exemple. Alors, plutôt que de répéter continuellement les mêmes instructions, on les écrit une fois et on les utilise plusieurs fois. Cela est équivalent à la notion de procédure en langage de haut niveau. Par exemple, lorsque le programme doit écrire un message à l'écran, il place l'adresse du début du message dans un des registres du microprocesseur, puis la longueur du message dans un autre registre et exécute ensuite les instructions du BIOS qui feront en sorte de faire apparaître le message à l'écran. Une fois terminé, le microprocesseur revient poursuivre l'exécution des instructions du programme original.
Mais une question se pose. Si la procédure est déjà écrite dans le BIOS, une fois que le microprocesseur a terminé cette suite d'instructions, comment fait-il pour retourner poursuivre le programme où il était rendu ?
Une façon d'y arriver serait d'écrire l'adresse de retour dans un des registres du microprocesseur. Alors une fois la procédure terminée, le microprocesseur copierait cette adresse dans son registre IP et poursuivrait l'exécution à cet endroit. Mais il y a un problème majeur à cette méthode : si la procédure doit elle-même utiliser une autre procédure, elle devra écrire son adresse de retour dans ce même registre, écrasant alors l'adresse précédente.
Une meilleure façon de mémoriser les adresses de retour serait de les placer en mémoire de l'ordinateur, les unes à la suite des autres. Le mécanisme qui a été retenu s'appelle une pile en rappel à une pile d'assiettes dans un restaurant. Son fonctionnement est le suivant.
Une zone de mémoire est réservée pour la pile et un registre du microprocesseur (SP pour Stack Pointer) indique le début de cette zone. Lorsque le microprocesseur doit utiliser une procédure, il place le contenu de son registre d'instructions (IP) à l'endroit indiqué par le pointeur de pile et augmente la valeur de de dernier afin qu'il indique le prochain emplacement disponible. Il place ensuite l'adresse de la procédure dans son registre d'instruction et poursuit donc en exécutant les instructions de la procédure.
La procédure se termine par une instruction de retour. Cette instruction dit au microprocesseur de décrémenter la valeur du pointeur de pile (SP) pour qu'il indique l'endroit où a été placée l'adresse de retour, puis de placer cette adresse dans son registre d'instructions (IP) et de poursuivre son travail à cet endroit. Comme il s'agit de l'adresse que le microprocesseur avait placée là avant l'appel de la procédure, c'est donc l'adresse de la prochaine instruction du programme que le microprocesseur va continuer d'exécuter
Si la procédure a besoin d'appeler une deuxième procédure, elle fera de même, mais comme le pointeur de pile est déplacé, son adresse sera placée à côté de la précédente, évitant de l'écraser. Puis comme le pointeur de pile est replacé après le retour de la procédure, il indique bien le même endroit qu'avant l'appel de la deuxième procédure et le retour au programme principal se fera comme prévu.
Les procédures peuvent donc faire appel à d'autres procédures en chaîne et le retour se fera dans l'ordre. Chaque appel ajoute une nouvelle adresse de retour sur la pile, et chaque instruction de retour retire une adresse, libérant ainsi la pile pour autre chose.
En fait, ce mécanisme est tellement pratique que les langages de programmation s'en servent aussi pour certaines variables. En effet, les variables déclarées localement ne sont nécessaires que pendant le temps d'exécution de la procédure. Une fois la procédure terminée, elle ne sont plus utiles. Une façon simple de réserver de la mémoire pour ces variables est donc de déplacer le pointeur de pile un peu plus loin que nécessaire pour conserver l'adresse de retour. L'espace ainsi libéré sert à placer les valeurs des variables locales. Puis juste avant que la procédure ne se termine, le pointeur de pile est replacé où il était en arrivant dans la procédure et cette dernière peut donc se terminer normalement lorsqu'elle atteint l'instruction de retour.
C'est pourquoi les variables locales n'existent plus lorsque la procédure se termine. De plus, dans les langages de haut niveau, les paramètre sont passés à une procédure en les plaçant aussi sur la pile.