Le C a le concept de fonctions et de variables, l'assembleur / le code machine ne l'ont pas. Lorsque l'on veut passer des valeurs aux fonctions, cela doit être fait soit en utilisant les registres du processeur, soit une valeur en mémoire à un décalage fixe d'un registre (normalement le pointeur de pile désigné). Ainsi, lorsque nous sautons à une nouvelle adresse au début de notre fonction, les bonnes valeurs se trouvent aux bons endroits pour que la fonction fonctionne correctement. Il en va de même pour les valeurs de retour.
La manière dont cela fonctionne en pratique est définie dans un document qui décrit les conventions d'appel du système. La convention d'appel est unique à l'architecture du processeur et au système d'exploitation.
Sous Windows x86, un certain nombre de conventions d'appel sont utilisées. Dans la convention d'appel "cdecl", l'appelant place les fonctions sur la pile pour que le destinataire les utilise. Une fois la fonction terminée, l'appelant nettoie sa propre pile.
Les API Windows utilisent la convention d'appel "stdcall", qui est similaire au cdelc, sauf que le destinataire de l'appel nettoie la pile. (Cela signifie que les appels de fonction vararg ne peuvent pas être utilisés). Cette convention a l'avantage d'économiser de l'espace dans le code.
Windows dispose également d'une convention d'appel "fastcall" qui utilise des registres pour le passage des paramètres.
Puisque Windows permet de multiples conventions d'appel, le compilateur C (cl) étend le langage C avec __cdecl
, __stdcall
y __fastcall
. Ceci décore la déclaration de la fonction et permet au programmeur de spécifier la convention d'appel utilisée.
D'autres plateformes comme ARM, Itanium et autres ont leurs propres conventions d'appel.