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 :

Utilisation Assembleur : question générale


Sujet :

C++

  1. #1
    LEK
    LEK est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    715
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 715
    Par défaut Utilisation Assembleur : question générale
    Bonsoir, j'ai une question qui me trotte dans la tête depuis quelque temps : j'ai cru comprendre qu'en c++ il est possible d'inclure des instructions en assembleur : ceci est-if fait dans le but d'avoir une application plus rapide à l'exécution?. Mai s pourquoi ce traitement serait plus rapide? La compilation génère un exe qui contient déjà du code machine non?

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Ceci permet de choisir quelles instructions on veut éxecuter.
    Etant donné que le compilateur est généralement plus intelligent que nous pour choisir les instructions les plus optimisées, son utilisation est marginale.
    Il me semble que le domaine où c'est encore le plus utilisé est pour les instructions vectorisées, dont le support dans les différents compilateurs et optimiseurs n'est pas encore parfait.
    ça peut aussi servir pour la programmation lock-free, éventuellement.

  3. #3
    Membre émérite
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LEK
    La compilation génère un exe qui contient déjà du code machine non?
    1/ Le code généré par le compilateur n'est pas toujours optimum car le compilateur ne peut pas deviner ce que vous voulez faire exactement.

    2/ la microprogrammation. (programmaition des microcontroleurs = les "puces" qui pilotent les machines a laver etc.) Un programme en assembleur de 4K prendra 20K en C !!! (oui, des kilo octets tout mouillés !) Et quand on regarde l'assembleur généré par le C, les puristes de l'assembleur meurent de dépit !! Le C est LE langage de programmation pour les microcons. Les microcons que j'utilise embarquent une puissance de calcul typique des micro ordinateurs des années 80. Ca ne pédale pas vite et donc on a souvent besoin d'optimiser le code.

    3/ Dans une fonction C, on n'a pas accès à la pile. La pile est chasse gardée du compilateur (heureusement, je dirais). Si pour une question d'optimisation, tu veux fouiller/tripoter dans la pile, tu dois le faire en assembleur.

    4/ Histoiquement, j'espère ne pas dire de bêtises en affirmant que C est né avec Unix. C est le langage qui a permis d'écrire le système d'exploitation Unix. L'un et l'autre ont grandi en même temps mais au début, quand il n'y avait rien, ni le compilo ni l'OS, il a bien fallu commencer par quelque chose. Je suppose que dans ces temps héroïques, l'usage de l'assembleur dans des fonctions était absolument nécessaire à l'optimisation de l'OS.

    Voila quelques exemples. L'énorme limite c'est que tu perds toute espèce de compatibilité. donc en effet, ça limite la portée. perso, je ne recommanderais jamais de mettre de l'assembleur dans un code C. Même dans nos microcontroleurs, nous ne mettons que très rarement du code assembleur. Nous essayons de faire tout en C pur et dur. C'est pour te dire.
    OL

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    2/ la microprogrammation. (programmaition des microcontroleurs = les "puces" qui pilotent les machines a laver etc.)
    Le besoin de l'assembleur vient simplement du fait que l'on n'a pas d'OS.

  5. #5
    Membre émérite
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par loufoque
    Le besoin de l'assembleur vient simplement du fait que l'on n'a pas d'OS.
    C'est pas tout a fait exact. On programme les puces sur des simulateurs tres confortables sur micro ordinateur. On a tout ce qui faut : compileur, debugger, tout un environnement de simulation etc.

    Quand le programme est OK, on le flash sur la puce et là ... c'est la surprise ...

    Mais pour la programmation : on a un OS : celui de l'ordi ou est installé le simulateur-compilateur.

    OL

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    On a aussi besoin d'utiliser l'assembleur si on veut faire un appel dynamique de fonction dont le prototype n'est pas connu à la compilation : Sur PC, on a besoin d'un accès à la pile pour passer les paramètres.

    C'est ce que font des fonctions comme le IDispatch::Invoke() de COM/OLE, etc.
    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.

  7. #7
    Membre émérite
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Médinoc
    On a aussi besoin d'utiliser l'assembleur si on veut faire un appel dynamique de fonction dont le prototype n'est pas connu à la compilation : Sur PC, on a besoin d'un accès à la pile pour passer les paramètres.

    C'est ce que font des fonctions comme le IDispatch::Invoke() de COM/OLE, etc.
    je me trompe ou c'est la meme chose avec fprintf ? je me suis toujours pose la question de comment cette fonction est implementee : ni le nombre ni le type des arguments n'est connu a l'avance. A moins de depiler a la main en fonction de ce qu'on attend ... et kes kis passe si le nombre de valeurs passees est different de ce qu'on attend en fonction du format ? am la la ! que de mysteres (au moins pour moi )
    OL

  8. #8
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Je ne parle pas de l'environnement de programmation mais de celui d'execution.
    Quand on a un OS, c'est lui qui gère le matériel. Donc on n'a pas à faire d'assembleur pour piloter des machines, sauf dans les pilotes du noyau.

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    Citation Envoyé par ol9245
    je me trompe ou c'est la meme chose avec fprintf ? je me suis toujours pose la question de comment cette fonction est implementee : ni le nombre ni le type des arguments n'est connu a l'avance. A moins de depiler a la main en fonction de ce qu'on attend ... et kes kis passe si le nombre de valeurs passees est different de ce qu'on attend en fonction du format ? am la la ! que de mysteres (au moins pour moi )
    OL
    Non, les *printf sont faisables entièrement en C, puisque les arguments sont là. Ici, les arguments ont été placés statiquement sur la pile, puisque la fonction appelante savait quels arguments étaient à placer, donc pas d'assembleur nécessaire.
    Les *printf font juste un peu d'arithmétique de pointeurs, comme celle qu'on peut voir dans les macros tournant autour des va_list (spécialement va_start et va_arg).
    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.

  10. #10
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    je me trompe ou c'est la meme chose avec fprintf ? je me suis toujours pose la question de comment cette fonction est implementee : ni le nombre ni le type des arguments n'est connu a l'avance. A moins de depiler a la main en fonction de ce qu'on attend ... et kes kis passe si le nombre de valeurs passees est different de ce qu'on attend en fonction du format ? am la la ! que de mysteres
    C'est pas exactement la même chose. Le standard définit des macros (les va_list) pour récupérer les paramètres des fonctions prenant nombre et type de paramètres inconnus. En gros ça va aller pointer sur le premier paramètre, et effectuer des décalage / transtypages pour accéder aux autres paramètres (les paramètres sont empilés dans l'ordre et de manière contigüe sur la pile).
    Bien évidemment si le type ne correspond pas avec ce que l'on attend, le comportement est indéterminé.

  11. #11
    Membre émérite
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Laurent Gomila
    C'est pas exactement la même chose. Le standard définit des macros (les va_list) pour récupérer les paramètres des fonctions prenant nombre et type de paramètres inconnus. En gros ça va aller pointer sur le premier paramètre, et effectuer des décalage / transtypages pour accéder aux autres paramètres (les paramètres sont empilés dans l'ordre et de manière contigüe sur la pile).
    Bien évidemment si le type ne correspond pas avec ce que l'on attend, le comportement est indéterminé.
    Oui, mais quand on fait des fonctins à passage d'argument variable, il y a toujours un truc pour aider la fonction à s'y retrouver. par exemple le dernier argument est un zéro, ou bien le premier argument contient le nombre d'aruùents passés. Pour printf, il n'y a rien (au moins côté utilisateur). Or, si mon format est "%f %f" mais que finalement je ne passe qu'un seul réel, j'ai aps souvenir que ça provoque un plantage. donc la fonction <sait> qu'il n'y a qu'un seul nombre empilé !! Mieux : les formats sont les mêmes pour les float et les double, les unsighed char et les long. donc forcément, il y a des indications cachées qui sont passées sur la pile par le compilo (en assembleur ?) et dépilées par printf. c'est ce que je me dis en tous cas...
    OL

  12. #12
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Or, si mon format est "%f %f" mais que finalement je ne passe qu'un seul réel, j'ai aps souvenir que ça provoque un plantage
    Je n'ai pas dit plantage, j'ai dit comportement indéterminé. Ici printf ira lire l'élément qui se trouve sur la pile après le flottant, et selon ce que c'est on aura un plantage, n'importe quoi d'affiché, ou, au pire, rien d'anormal.

    Mieux : les formats sont les mêmes pour les float et les double, les unsighed char et les long. donc forcément, il y a des indications cachées qui sont passées sur la pile par le compilo (en assembleur ?) et dépilées par printf
    Je ne pense pas non. Par contre c'est vrai que je ne sais pas comment il fait la distinction entre les différents types qui partagent un même symbole de formattage.

  13. #13
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    3/ Dans une fonction C, on n'a pas accès à la pile. La pile est chasse gardée du compilateur (heureusement, je dirais). Si pour une question d'optimisation, tu veux fouiller/tripoter dans la pile, tu dois le faire en assembleur.
    Je ne vois vraiment pas quelles optimisations tu peux faire.
    Les compilateurs actuels ont des systèmes d'allocation de registres très bien faits.
    La seule chose éventuellement gênante, c'est la convention d'appels des fonctions, qui, dans l'ABI C, ne fait pas d'usage des registres et est donc peu optimisée.
    Mais c'est uniquement lié à l'ABI, et certains compilateurs permettent de choisir la convention d'appel pour les fonctions.

  14. #14
    Membre émérite
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par loufoque
    Je ne vois vraiment pas quelles optimisations tu peux faire.
    pour moi, en pratique, ça se limite à quelques interventions dans la programmation des microcon. La possibilité d'encapsuler de l'assembleur dans du C est de mon point de vue un héritage du passé de ce langage. Ceci dit, je suis sur que ceux qui le font ont de bonnes raisons pour ça car ils savent qu'ils perdent la portabilité de leur code.
    Citation Envoyé par loufoque
    Les compilateurs actuels ont des systèmes d'allocation de registres très bien faits.
    C'est exact. je le vérifie régulièrement y-compris pour le compilateur de microcontroleurs que j'utilise. Il reconnait bien les variables à courte durée de vie qu'il peut stocker dans des registres.
    Citation Envoyé par loufoque
    La seule chose éventuellement gênante, c'est la convention d'appels des fonctions, qui, dans l'ABI C, ne fait pas d'usage des registres et est donc peu optimisée.
    Mais c'est uniquement lié à l'ABI, et certains compilateurs permettent de choisir la convention d'appel pour les fonctions.
    Effectivement, en assembleur, on passe souvent par registre les arguments aux fonctions. Et les résultats booléens sont retournés dans la "carry". Tout cela n'est pas possible en C.

    OL

  15. #15
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Citation Envoyé par ol9245
    Oui, mais quand on fait des fonctins à passage d'argument variable, il y a toujours un truc pour aider la fonction à s'y retrouver. par exemple le dernier argument est un zéro, ou bien le premier argument contient le nombre d'aruùents passés. Pour printf, il n'y a rien (au moins côté utilisateur). Or, si mon format est "%f %f" mais que finalement je ne passe qu'un seul réel, j'ai aps souvenir que ça provoque un plantage. donc la fonction <sait> qu'il n'y a qu'un seul nombre empilé !! Mieux : les formats sont les mêmes pour les float et les double, les unsighed char et les long. donc forcément, il y a des indications cachées qui sont passées sur la pile par le compilo (en assembleur ?) et dépilées par printf. c'est ce que je me dis en tous cas...
    OL
    Le seul moyen pour *printf de savoir ce qu'on lui a passé en argument, c'est la chaine de formatage. C'est d'ailleurs un moyen d'aller trifouiller la pile, j'étais tombé sur un exemple d'un programme qui appelait une fonction en mettant son adresse dans la pile de telle façon que le retour de sous-programme arrivait sur cette adresse.

    Pour les fonctions à nombre variable d'arguments, c'est l'appelant qui ve nettoyer la pile. Dans ton exemple de printf("%d %d", 42), tu vas avoir l'affichage de 42 et de l'entier qui est juste en dessous sur la pile, typiquement l'adresse de retour.

    Sous win32, j'imagine que tous les entiers passés en paramètre/retour sont convertis en int (de taille 32 bits), et que idem les float sont convertis en double. Ce qui dans ce cas posera un vrai problème si on fait un printf("%f %d", 42, 1).


    Sinon Laurent, je ne vois pas de différence entre *printf et les va_lists. À quoi penses-tu ?

  16. #16
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    Citation Envoyé par Ulmo
    je ne vois pas de différence entre *printf et les va_lists
    La va_list sert à parcourir les arguments. gcc empêche la création d'une va_list, ce qui fait qu'elle ne peut pointer QUE sur les arguments variables.

    Avec les va_list, la version "arguments variables" d'une fonction peut être un simple wrapper de la fonction va_list :
    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 fonction(int a, ...)
    {
       int ret;
       va_list v;
       va_start(v, a);
       vfonction(a, v);
       va_end(v);
       return ret;
    }
     
    int vfonction(int a, va_list v)
    {
       ...
    }
    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.

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/09/2012, 22h46
  2. Question générale quant à l'utilisation d'un Framework PHP
    Par J.Walsh dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 20/01/2012, 11h05
  3. [LDAP] Questions générales sur LDAP
    Par guiguisi dans le forum Autres SGBD
    Réponses: 5
    Dernier message: 25/05/2005, 10h05
  4. Question générale sur les affectations ?
    Par Clemaster dans le forum C++
    Réponses: 5
    Dernier message: 09/08/2004, 17h03
  5. [SGBD]Questions générales.
    Par Mobaladje dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 21/05/2004, 19h19

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