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

Assembleur Discussion :

Blocs try catch et asm


Sujet :

Assembleur

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 6
    Points : 11
    Points
    11
    Par défaut Blocs try catch et asm
    Bonjour,

    je me pose pas mal de question vis à vis des blocs try{} catch() {} du c++, une fonctionnalité que j'utilises énormément mais dont j'ai très peu de connaissances vis à vis du fonctionnement interne, voici mes questions :
    - comment les try/catch, ainsi que les instructions throw sont-elles gérées au niveau assembleur ?
    - quel code asm génère un compilo c++ comme gcc pour gérer cette fonctionnalité ?
    - quelle est la différence en bas niveau entre une exception lancée par un throw du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if (dadou == 0)
       throw new Exception("Dadou is NULL !");
    et une exception intrinsèque du CPU comme une division par zero ?

    - est-ce qu'englober un bloc de code dans un try/catch va allourdir l'exécution ?
    - existe-t-il des failles de sécurité concernant les blocs try/catch qui requièrent une certaine prudence lors du codage d'une appli ?

    Si quelqu'un pouvait me rediriger vers un article simple, ou me filer une explication çà m'intéresse vraiment, j'ai la facheuse habitude de balancer des try/catch à la volée sans vraiment réfléchir.

  2. #2
    Membre émérite
    Avatar de supersnail
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 719
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 719
    Points : 2 793
    Points
    2 793
    Par défaut
    Bonjour,

    Les try/catch n'existent tout simplement pas en assembleur. Sous Windows, il existe un mécanisme de SEH handler, qui est expliqué ici: http://www.indahax.com/reverse/struc...eption-handler (à noter que les try/catch en C++ se servent de ce système ).
    Cependant, je n'ai aucune idée concernant l'implémentation des exception handler sous Linux et UNIX en général...
    Toute question technique envoyée en MP ira directement à la poubelle

    Un code ne marchera jamais, il n'a jamais reçu la capacité de se déplacer.
    Inutile donc de dire "ça marche pas", donnez plutôt des informations précises afin de mieux pouvoir vous aider.


    Grand gourou de la -attitude

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Bonjour !

    Alors, dans le désordre :

    Tu peux voir directement le code assembleur produit par GCC avec l'option « -S ». C'est très instructif, surtout en fonction des différents niveaux d'optimisation « -O » ;

    Pour le reste, les exceptions CPU et les exceptions C++ ne sont pas du tout les mêmes. Elles portent le même nom car il s'agit de traiter le même genre de problème, mais chacun à leur niveau. Dans le cas de la division, le calcul est effectué électroniquement par le micro-processeur lorsqu'il dispose d'une instruction pour le faire (cas des x86) sauf bien sûr dans le cas où le diviseur est nul. Tous les nombres peuvent donc être traités à l'exception de ce cas précis.

    C'est d'ailleurs de là que vient le terme : il s'agit de gérer les situations qui font exception à la règle générale de traitement. Mais avec la « jargonisation » des notions informatiques et avec la programmation orientée objet, « l'exception » est devenue une sorte d'entité, et c'est elle que l'on traite, plutôt que la situation dans laquelle on se trouve. C'est un abus de langage, comme en ont été victimes les notions de « registre » ou de « vecteur » par exemple.

    Quoi qu'il en soit, le micro-processeur ne peut pas honorer l'instruction qui lui a été donné et ça, ce n'est pas un cas prévu de manière générale au niveau de l'assembleur : les instructions ne renvoient pas de « code d'erreur » ou de statut comme une fonction en C. Elles sont censées fonctionner tout le temps. Donc, dans ce cas de figure identifié mais en dehors du cadre normal de traitement, le micro-processeur va appeler une de ses interruptions, comme indiqué sur cette page :

    http://support.microsoft.com/kb/117389

    Donc, dans le cas d'une division par zéro, le micro-processeur va automatiquement faire l'équivalent de « int 00h ». À charge du concepteur du système d'exploitation de placer derrière cette interruption une routine permettant au programme de se terminer si nécessaire et de ramener le système dans le dernier état stable connu.

    À noter que tous les cas de figure d'exception identifiés, au niveau de du micro-processeur, donnent lieu à un appel similaire et que le vecteur utilisé est défini « en dur » par le concepteur de la puce (ici Intel). Tu ne peux donc pas mapper le traitement de la division par zéro sur un autre vecteur que celui de « int 00h ».

    Tout cela n'est vrai que pour ce qui concerne directement le micro-processeur. Si tu fais une division « logicielle » par 0, autrement dit si tu utilises une routine effectuant le calcul, c'est ton logiciel qui va s'apercevoir que le diviseur est nul et qui va s'orienter ensuite vers la procédure de son choix.


    En ce qui concerne le C++ à présent, une exception est traitée comme une sortie de bloc, telle que tu la ferais avec break ou return. Autrement dit, on interrompt la séquence en cours et on saute directement à l'endroit où l'on va être capable de retomber sur ses pieds. Ça veut dire qu'il s'agit d'un goto, celui-là même qu'on t'enseigne en général à ne jamais utiliser. C'est d'ailleurs un des rares cas où on l'utilise en C.

    Par contre, on voit que les exceptions C++ sont gérées par lui-même et ne sont en aucune façon l'affaire du micro-processeur.

    À noter enfin que « throw new Exception », c'est plus du Java que du C++ (même si ça reste valide dans une certaine mesure). D'abord, le C++ peut lancer n'importe quelle donnée. Par exemple, tu peux très bien lancer un entier en faisant « throw 5 » et « catch (int) ». Ensuite, si tu utilises new, il faudra explicitement rattraper ce pointeur et effacer l'objet concerné avec delete.

    Tu pourrais donc très bien te contenter de lancer un numéro de séquence, voire même tout simplement l'état du pointeur de programme (soit l'adresse de l'instruction en cours d'exécution). L'intérêt de lancer un objet dans ce cas précis est principalement la possibilité d'utiliser l'héritage : si le cas de figure ne peut pas être traité au niveau local, il pourra l'être à un niveau plus général si tu utilises des catch imbriqués. Et la possibilité de spécialiser les problèmes de manière de plus en plus fine se prête bien à ce genre de traitement.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 6
    Points : 11
    Points
    11
    Par défaut
    Alors merci beaucoup.

    J'ai lu la sortie asm de g++, et les exceptions c++ sont en effet gérées par du code supplémentaire sur mon linux i686, et j'ai été très con de poser la question sur les exceptions matérielles, le systeme balance un signal SIGFPE au processus qui fait une division par zero, tout comme une SIGSEGV pour les segfaults, alors que les exceptions c++ (throw, try, catch) sont en fait gérées par des subroutines que le compilateur rajoute (c'est incroyable tout ce que ce compilo peut rajouter en fait !).

    En gros pour chopper une "floating point exception", qui inclus l'exception de division par zéro, il doit falloir écrire un gestionnaire de signaux, ce qui est complètement différent.

    L'implémentation des exceptions c++ (fonctions d'allocation, de lancement, de recuperation) sous Linux est fortement ressemblante à l'implémentation Windows, j'ai trouvé l'explication complete sur http://www.codesourcery.com/public/c...h.html#cxx-abi, après il est possible que la lib qui gère çà change avec les archis, mais çà correspond à la mienne. Je ne me suis pas encore plongé dedans, mais je compte le faire, j'ai juste vu vite fait que les exceptions étaient allouées sur le tas, et organisées en listes châinées comme sur Win.

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par artefactman Voir le message
    Alors merci beaucoup. J'ai lu la sortie asm de g++, et les exceptions c++ sont en effet gérées par du code supplémentaire sur mon linux i686, et j'ai été très con de poser la question sur les exceptions matérielles, le systeme balance un signal SIGFPE au processus qui fait une division par zero, tout comme une SIGSEGV pour les segfaults,
    Au contraire, la question est pertinente et il est important de faire le distingo. Cela dit, le système envoie SIGFPE ou SIGSEGV parce que le micro-processeur a lui-même déclenché une exception matérielle. Le système pouvant par ailleurs envoyer d'autres signaux qui ne sont nullement liés au matériel.

    alors que les exceptions c++ (throw, try, catch) sont en fait gérées par des subroutines que le compilateur rajoute (c'est incroyable tout ce que ce compilo peut rajouter en fait !).
    Oui, mais justement, ce n'est pas à proprement parler du code « caché » : il faut considérer les exceptions C++ comme des goto explicites vers le premier bloc dont la signature correspond à celle de l'objet lancé.

    En gros pour chopper une "floating point exception", qui inclus l'exception de division par zéro, il doit falloir écrire un gestionnaire de signaux, ce qui est complètement différent.
    Certes, mais sous certaines conditions, tu peux lancer une exception depuis le gestionnaire.

Discussions similaires

  1. Réponses: 10
    Dernier message: 06/10/2010, 17h06
  2. Visibilité de mon tableau dans bloc try catch
    Par erox44 dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 18/05/2010, 15h13
  3. répétition d'un bloc try/catch
    Par hadler dans le forum Général Java
    Réponses: 4
    Dernier message: 03/12/2009, 15h09
  4. Le Bloc Try/Catch
    Par freestyle59 dans le forum Langage
    Réponses: 2
    Dernier message: 25/03/2009, 14h17
  5. Faire un return dans un bloc try catch
    Par alizee971 dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 13/08/2008, 19h38

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