Les instructions call et ret permettent respectivement d'appeler et de sortir d'une procédure. L'opérande qui suit call est l'adresse symbolique de la procédure. Traditionnellement, les paramètres de la procédure sont passés par la pile.
call empile tout d'abord l'adresse de la prochaine instruction (le contenu de %rip) et remplace le contenu de rip par l'adresse donnée en opérande. ret dépile et place la valeur dépilée dans rip, ce qui provoque (sauf erreur de programmation) le retour à l'endroit où la procédure à été appelée (instruction qui suit le « call adresse »).
Comme la pile n'est pas uniquement utilisée pour sauvegarder l'adresse de retour mais aussi pour stocker les paramètres et les variables locales de la procédure, il est important de s'assurer que le haut de la pile contient bien l'adresse de retour avant l'exécution de ret.
ret peut avoir une opérande n de type constante entière. Dans ce cas, ret dépilera l'adresse de retour, puis n octets avant de retourner à la procédure appelante. Le registre rbp (re-extended base pointer) est souvent utilisé par le programmeur pour accéder aux différentes zones de la pile, il pointe généralement sur l'adresse de retour de la procédure.
Voici un exemple de procédure qui prend 2 entiers non signés comme paramètres (par la pile) et renvoie le maximum des 2 valeurs :
Voici un schéma qui illustre l'exécution de procédures imbriquées. Les chiffres représentent l'ordre d'exécution du code :
Et voici l'évolution de la pile lors de l'exécution schématisée ci-dessus :
-
1.{}
-
2.{adresse de 5}
-
3.{adresse de 5, adresse de 4}
-
4.{adresse de 5}
-
5.{}
-
6.{adresse de 7}
-
7.{}