IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Problème de compréhenssion de __cdecl


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Inscrit en
    Décembre 2006
    Messages
    103
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 103
    Par défaut Problème de compréhenssion de __cdecl
    Bonjour à tous,
    après l'avoir vu de nombreuses fois et ayant rien compris à tous les articles trouvés sur, je voudrais en savoir plus sur le rôle de __cdecl .
    (Oui, je sais, c'est pas forcément facile à répondre, mais j'ai vraiment rien compris )
    Je tiens à préciser, au cas où, que j'ai googlé pendant 3 jours, sans que ça m'éclaire.
    Merçi d'avance !

  2. #2
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    Bonjour,

    la convention d'appel cdecl est une convention d'appel de l'architecture x86 (16 et 32 bits, l'archi. x86-64 n'utilise plus que deux convention).

    Les conventions d'appels ont un impact visible uniquement au niveau de l'assembleur.

    En ce qui concerne la convention cdecl, c'est la convention par défaut des compilateurs C pour x86. Dans cette convention on distingue les particularités suivantes :

    - Les paramètres d'une fonction ayant un type d'appel cdecl sont poussés de droite à gauche.

    - Il est de la responsabilité de l'appelant (i.e : de la fonction appelante) de nettoyer la pile après un appel à une fonction ayant une convention cdecl.

    - La valeur de retour de la fonction se fait sur le registre d'accumulation (EAX en 32 bits, AX en 16 bits).

    Ex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    int foo(int param1, int param2, int param3);
     
    /* cut */
     
     
    int bar (void)
    {
         int a = 0, b = 0, c = 0, result;
     
         result = foo(a, b, c);
     
         return result;
    }
    L'appel de la fonction foo en assembleur (x86 32 bits):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
         /* assembleur */
         push c; /* on pousse d'abord 'c' puisque c'est le param. le + à droite */
         push b;
         push a;
         call foo; /* appel de la fonction foo. */
         add esp, 12; /* nettoyage de la pile */
         mov result, eax; /* sauve le résultat de EAX dans "result" */
    ESP [extended stack pointer]est le "stack pointer" (pointeur de pile) chargé de maintenir la pile localement à la fonction (un stack frame).

    On ajoute 12 au pointeur de pile (ce qui enlève 12 octets, soit 3 double-mots) car :

    - Sous x86 (32 bits) un int fait 4 octets [4 * 8 = 32 bits].
    - Il y a 3 paramètres à la fonction, soit : 4 * 3 = 12 octets.

    Tu trouvera, en détail, les conventions d'appel x86 sur wikipedia (en) :

    http://en.wikipedia.org/wiki/X86_calling_conventions

    N'hésite pas si tu as des questions.

  3. #3
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par 30barrett40 Voir le message
    Bonjour à tous,
    après l'avoir vu de nombreuses fois et ayant rien compris à tous les articles trouvés sur, je voudrais en savoir plus sur le rôle de __cdecl .
    (Oui, je sais, c'est pas forcément facile à répondre, mais j'ai vraiment rien compris )
    Je tiens à préciser, au cas où, que j'ai googlé pendant 3 jours, sans que ça m'éclaire.
    Merçi d'avance !
    1 - Il ne s'agit pas d'un mot clé standard.
    2 - Il est préfixé par un _ (même 2), donc il ne concerne pas l'utilisateur mais uniquement l'implémentation.
    3 - La définition exacte dépend de l'implémentation, il n'y a donc pas de réponse universelle.

    Attention, la suite est technique et n'a pas grand intérêt pour un programmeur d'application...

    4 - Sur les implémentation que je connais, cdecl signifie C-declaration, par opposition à pascal (Pascal-declaration). En gros, ça veut dire que la traduction d'un appel de fonction (passage de paramètres, adresse de retour, correction de pile) se fait selon une certaine technique qui permet, notamment, le passage d'un nombre variable de paramètres (printf() etc.). La méthode 'pascal' est différente et ne permet pas ça. C'est celle qui est utilisée depuis les origines de Windows pour implémenter les interfaces de l'API Windows, et plus généralement des fonctions de DLL (bien que je n'en suis pas sûr à 100%, car à l'évidence MSVCRT.DLL a des conventions d'appel cdecl).

    Ce choix vient de ce que la convention 'Pascal' est celle utilisée nativement par le BASIC, et notamment Visual BASIC qui a longtemps été le seul outil de développement d'applications sous Windows (et qui convenait parfaitement à Delphi, une déclinaison du Pascal par Borland orienté développement Windows).

    Quand les outils 'orientés C' (Microsoft C, Visual C++ etc.) sont apparus, Microsoft (et les implémenteurs indépendants) ont créé cette différentiation entre conventions d'appel C et Pascal de façon à pouvoir générer le bon code en fonction des besoins :
    • appels locaux : cdecl
    • appels externes (API Windows) : pascal (maintenant, on dit WINAPI, mais l'effet est le même...)

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    En fait, il y a trois conventions d'appel en C sous Windows, sur un x86 :
    • __cdecl, la convention d'appel C habituelle. Obligatoire pour des fonctions variadic comme printf(). Il est dit ici que VB était incapable d'appeler des fonctions C avec cette convention d'appel.
    • __stdcall, la "convention d'appel pascal". C'est la convention d'appel utilisée par les fonctions de Windows, les fonctions passées en callback à Windows, et les méthodes des interfaces COM.
    • __fastcall, une légère modification sur la convention d'appel __stdcall : Les deux premiers paramètres passent par des registres au lieu de la pile. Rarement utilisée (pour des raisons qui me sont inconnues) par Windows, mais systématiquement utilisée dans le code généré par Borland C++.

    Plus d'infos sur les conventions d'appel (en Anglais) :
    Argument Passing and Naming Conventions
    The history of calling conventions, part 3 sur le blog de Raymond Chen.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre éprouvé
    Inscrit en
    Décembre 2006
    Messages
    103
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 103
    Par défaut
    Merci de toutes vos réponses, j'ai compris à quoi il sert.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de compréhenssion d'un CSS
    Par jpean.net dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 22/12/2007, 12h29
  2. [VB]Problème de compréhenssion
    Par LiNuXaDDiKt dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 05/02/2006, 18h52
  3. Problème d'installation oracle 8.1.7 sous NT
    Par Anonymous dans le forum Installation
    Réponses: 7
    Dernier message: 02/08/2002, 14h18
  4. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10
  5. Réponses: 6
    Dernier message: 25/03/2002, 21h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo