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

x86 32-bits / 64-bits Assembleur Discussion :

[runtime exception] Floating point exception


Sujet :

x86 32-bits / 64-bits Assembleur

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Juin 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2008
    Messages : 32
    Par défaut [runtime exception] Floating point exception
    Bonjour à tous,

    je suis un cours de compiler design dans lequel on doit créer un compilateur de a à z.
    Le langage à implémenter est un sous-set de C.
    La cible principale du langage est l'architecture x86-64.

    Je n'ai malheureusement pas beaucoup de connaissances en assembleur et ça me pose pas mal de problèmes par ailleurs. En voici un pour lequel je ne comprends pas l'erreur :

    Le code original est bêtement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main()
    {
      int x1;
     
      x1 = 80;
      x1 /= 3;   // 26
      x1 *= 4;   // 104
      x1 -= 4;   // 100
      x1 += -17; // 83 
      x1 %= 10;  // 3
     
      return x1;
    }
    que mon compilateur traduit en assembleur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    .section .text
     
      .type _start, @function
      .globl _start
    _start:
        pushq %rbp
         movq %rsp, %rbp
        movl $80, %eax
        movl $3, %edx
        cltd
        idivl %edx
        imull $4, %eax
        subl $4, %eax
        addl $-17, %eax
        movl $10, %edx
        cltd
        idivl %edx
        movl %edx, %eax
        leave
        ret
      .size  _start, .-_start
    Le problème semble venir de la division que j'effectue (deux fois).
    L'erreur à l'exécution est :

    14880 Floating point exception(core dumped) ./a.out 2>&1 >a.result
    Execution of binary unexpectedly failed with exception 8.
    Que fais-je de faux ?
    La valeur retournée devrait être 3 à la fin, mais le programme ne s'exécute pas jusqu'à la fin : il lève cette exception avant.

    En passant, j'ai trouvé l'ABI d'AMD64, mais c'est affreux à lire, et ça sous-entend qu'on connaît déjà toutes les informations à propos de l'assembleur x86 32bits... avez-vous des ressources plus intéressantes pour comprendre comment faire telle ou telle opération en assembleur ?

    Ajout : à noter que toutes les opérations sont à effectuer sur des entiers signés 32bits, soit de -2^31 à 2^31-1. La multiplication et la division (ainsi que le modulo) sont signés. Les opérations sont toutes des opérations entières.
    Les under-overflows par additions/soustraction/multiplication ne doivent pas lever d'exception (à la place, on utilise la modulo 2^32.
    e.g. -(2^31)=>-(-2^31)=>2^31=>-2^31
    e.g. -2^31-1=>2^31-1

    Les seules exceptions qui doivent être levées sont lors des divisions / modulos :
    1. si on divise par zero
    2. si le signe de la division cause un overflow (-2^31 / -1, ou -2^31%-1)

  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,

    A priori, le problème vient du "cltd" ('CDQ' pour le mnémonique Intel) ou bien le fait que tu passes certaines des valeur immédiates dans EDX avant un cltd:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        movl $80, %eax  ; eax = 80
        movl $3, %edx   ; edx = 3
        cltd            ; eax = 80 ; edx = 0
        idivl %edx      ; edx:eax / edx => 80 / 0 => [divide by 0]
    CLTD étend le signe de EAX dans EDX (EAX -> EDX:EAX). Du coup tu te retrouves avec EDX = 0 après le CLTD, donc "divide by 0" sur le IDIV.

    Si tu veux propager le signe de EAX dans RAX, utilise "CLTQ" (CDQE).

    Concernant l'ABI64 c'est effectivement très aride, comme la plupart des spécifications. Le mieux est de se concentrer sur l'essentiel:

    - Conventions d'appel en 64 bits (type "fastcall")
    - Obligation pour le 'callee' (fonction appelée) de préserver les registres.
    - Obligation d'alignement de la pile avant un appel.

    En gros, dans l'ABI64, concentre toi sur "Stack Frame" et "Parameter Passing" (chapitre "Function calling sequence").

  3. #3
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Juin 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2008
    Messages : 32
    Par défaut
    Ouch, merci beaucoup pour votre aide !

    "You made my day !"

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

Discussions similaires

  1. Floating point exception error while executing tcl with ns2
    Par ines8989 dans le forum Développement
    Réponses: 0
    Dernier message: 11/04/2013, 19h01
  2. Floating point exception sous linux
    Par doommick31 dans le forum C++
    Réponses: 4
    Dernier message: 20/12/2012, 18h22
  3. Floating Point Exception
    Par étoile de mer dans le forum Débuter
    Réponses: 3
    Dernier message: 28/10/2009, 17h09
  4. Réponses: 1
    Dernier message: 06/05/2009, 16h36
  5. Floating point exception dans dlopen()
    Par Invité dans le forum C++
    Réponses: 0
    Dernier message: 10/06/2008, 09h56

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