El cdecl
(déclaration C) est généralement la convention d'appel par défaut des compilateurs C x86.
En informatique, une convention d'appel est un schéma d'implémentation (de bas niveau) pour la façon dont les sous-routines reçoivent des paramètres de leur appelant et comment elles retournent un résultat. Les différences entre les diverses implémentations incluent l'emplacement des paramètres, des valeurs de retour, des adresses de retour et des liens de portée (registres, pile ou mémoire, etc.), ainsi que la répartition des tâches de préparation d'un appel de fonction et de restauration de l'environnement entre l'appelant et l'appelé.
_(Source)_
Les conventions d'appel peuvent être liées à la stratégie d'évaluation d'un langage de programmation particulier, mais le plus souvent elles ne sont pas considérées comme en faisant partie (ou vice versa), car la stratégie d'évaluation est généralement définie à un niveau d'abstraction plus élevé et considérée comme faisant partie du langage plutôt que comme un détail d'implémentation de bas niveau du compilateur d'un langage particulier.
_(Source)_
El cdecl
(qui signifie "déclaration C") est une convention d'appel qui provient du compilateur de Microsoft pour le langage de programmation C et qui est utilisée par de nombreux compilateurs C pour l'architecture x86. Dans cdecl
les arguments des sous-programmes sont passés sur la pile. Les valeurs entières et les adresses de mémoire sont renvoyées dans la section EAX
les valeurs à virgule flottante dans le registre ST0
Registre x87. Registres EAX
, ECX
et EDX
sont sauvegardés par l'appelant, et les autres sont sauvegardés par l'appelant. Les registres à virgule flottante de x87 ST0
à ST7
doit être vide (vidée ou libérée) lors de l'appel d'une nouvelle fonction, et ST1
à ST7
doit être vide à la sortie d'une fonction. ST0
doit également être vide lorsqu'elle n'est pas utilisée pour renvoyer une valeur.
Dans le contexte du langage de programmation C, les arguments des fonctions sont poussés sur la pile dans l'ordre de droite à gauche, c'est-à-dire que le dernier argument est poussé en premier.
Considérons l'extrait de code source C suivant :
int callee(int, int, int);
int caller(void)
{
return callee(1, 2, 3) + 5;
}
Sur x86, il pourrait produire le code assembleur suivant (syntaxe Intel) :
caller:
; make new call frame
; (some compilers may produce an 'enter' instruction instead)
push ebp ; save old call frame
mov ebp, esp ; initialize new call frame
; push call arguments, in reverse
; (some compilers may subtract the required space from the stack pointer,
; then write each argument directly, see below.
; The 'enter' instruction can also do something similar)
; sub esp, 12 : 'enter' instruction could do this for us
; mov [ebp-4], 3 : or mov [esp+8], 3
; mov [ebp-8], 2 : or mov [esp+4], 2
; mov [ebp-12], 1 : or mov [esp], 1
push 3
push 2
push 1
call callee ; call subroutine 'callee'
add esp, 12 ; remove call arguments from frame
add eax, 5 ; modify subroutine result
; (eax is the return value of our callee,
; so we don't have to move it into a local variable)
; restore old call frame
; (some compilers may produce a 'leave' instruction instead)
mov esp, ebp ; most calling conventions dictate ebp be callee-saved,
; i.e. it's preserved after calling the callee.
; it therefore still points to the start of our stack frame.
; we do need to make sure
; callee doesn't modify (or restores) ebp, though,
; so we need to make sure
; it uses a calling convention which does this
pop ebp ; restore old call frame
ret ; return
L'appelant nettoie la pile après le retour de l'appel de fonction.
El cdecl
est généralement la convention d'appel par défaut des compilateurs C x86, bien que de nombreux compilateurs fournissent des options permettant de modifier automatiquement les conventions d'appel utilisées. Pour définir manuellement une fonction qui sera cdecl
certains supportent la syntaxe suivante :
return_type __cdecl func_name();
Calling convention est le nom de la convention d'appel. __cdecl
, __stdcall
, __pascal
y __fastcall
peuvent être spécifiées explicitement dans les déclarations de fonctions C++ pour les compilateurs qui supportent ces conventions. __cdecl
est la valeur par défaut pour les applications et les bibliothèques statiques. __stdcall
est par défaut pour les appels système (y compris les appels de l'API Windows) et recommandé pour les bibliothèques DLL sous Windows 32 bits. __thiscall
est utilisé par défaut dans les compilateurs Microsoft pour les membres en mode 16 et 32 bits. Microsoft, Borland, Watcom et Gnu sont des marques de compilateurs. Les compilateurs Intel pour Windows sont compatibles avec Microsoft. Les compilateurs Intel pour Linux sont compatibles avec Gnu. Les compilateurs Symantec, Digital Mars et Codeplay sont compatibles avec compatibles avec Microsoft. En mode 64 bits, il existe une convention d'appel par défaut pour chaque système d'exploitation. système d'exploitation, tandis que les autres conventions d'appel sont rares en mode 64 bits.
Autres conventions :
- __pascal
- __fortran
- __thiscall
- __stdcall
- __fastcall
- __msfastcall
- __regcall
- __vectorcall
_(Source)_