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 :

Assembleur et gcc [Débutant(e)]


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut Assembleur et gcc
    Bonjour.

    Considérons le code C suivant contenu dans un fichier "main.cpp" .

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(){
    int a = 5;
    a = a + 2;
    return 0;
    }

    Sous Linux Ubutnu, la commande "gcc -S main.cpp" renvoie le code assembleur suivant.

    Code Assembleur : 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
    22
        .file    "main.c"
        .text
    .globl main
        .type    main, @function
    main:
    .LFB0:
        .cfi_startproc
        pushq    %rbp
        .cfi_def_cfa_offset 16
        movq    %rsp, %rbp
        .cfi_offset 6, -16
        .cfi_def_cfa_register 6
        movl    $3, -4(%rbp)
        addl    $2, -4(%rbp)
        movl    $0, %eax
        leave
        ret
        .cfi_endproc
    .LFE0:
        .size    main, .-main
        .ident    "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
        .section    .note.GNU-stack,"",@progbits

    Dans le code précédent, ce qui m'intéresse ce sont les lignes suivantes.

    Code Assembleur : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        pushq    %rbp
        .cfi_def_cfa_offset 16
        movq    %rsp, %rbp
        .cfi_offset 6, -16
        .cfi_def_cfa_register 6
        movl    $3, -4(%rbp)
        addl    $2, -4(%rbp)
        movl    $0, %eax
        leave

    Quelqu'un pourrait-il m'expliquer un peu ces lignes ? Existe-t-il une documentation expliquant les mots clés ?

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    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 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Bonjour,

    Les lignes commençant par « .cfi » et d'une manière générale par « . » sont des directives à l'intention du compilateur. Elles ne font pas partie du programme proprement dit. Ensuite, le code généré est de l'assembleur Intel mais en utilisant la syntaxe AT&T, avec des « % » et avec l'opérande source à gauche, la destination à droite.

    Dans les lignes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        pushq    %rbp
        movq    %rsp, %rbp
    … on sauvegarde le registre BP (Base Pointer, appelé EBP sur i386 quand il a été étendu à 32 bits, puis RBP sur x86_64) dans la pile, puis on sauvegarde le pointeur de pile dans ce même registre, auquel on ne touchera plus. C'est le prologue classique d'une fonction : on sauvegarde le pointeur de pile pour pouvoir exploiter celle-ci comme on veut, notamment pour y stocker les variables locales. Ça nous permet si nécessaire de ramener d'un coup le pointeur de pile à son état initial et, de là, restaurer les registres et sortir de la fonction. Ensuite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        movl    $3, -4(%rbp)
        addl    $2, -4(%rbp)
        movl    $0, %eax
        leave
    Chez moi, j'obtiens « $5 » à la première ligne et c'est censé être pareil chez toi.

    Cette première ligne stocke la valeur initiale dans ta variable locale « a », qui est repérée en mémoire via un offset par rapport au pointeur de base (donc le pied du cadre de pile). La ligne suivante ajoute « 2 » à la même variable.

    Traditionnellement, on utilise l'accumulateur AX (donc EAX ou RAX selon le format) pour renvoyer la valeur de retour de la fonction, soit toujours zéro chez toi.

    Enfin, « LEAVE » est une instruction Intel x86 qui permet, en un seul code opération, de nettoyer le cadre de pile, de restaurer les bons registres et d'effectuer un « RET » pour revenir à la fonction appelante.

  3. #3
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Merci pour ces éclaircissements.

    Un truc me chagrine. Pourquoi stocke-t-on 5 avec la ligne suivante ?
    Je pose cette question car j'aurais penser voir $5 au lieu de $3... J'ai dû faire une faute de frappe quelque part...

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    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 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Citation Envoyé par rambc Voir le message
    Un truc me chagrine. Pourquoi stocke-t-on 5 avec la ligne suivante ? Je pose cette question car j'aurais penser voir $5 au lieu de $3... J'ai dû faire une faute de frappe quelque part...
    En effet, c'est ce que je disais juste au-dessus :

    Citation Envoyé par Obsidian Voir le message
    Chez moi, j'obtiens « $5 » à la première ligne et c'est censé être pareil chez toi.

    Essaie de recompiler pour voir si tu obtiens toujours le même résultat ou pas.

  5. #5
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Je confirme, j'ai mal recopié les codes...

    Merci pour toutes ces infos.

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

Discussions similaires

  1. code assembleur et gcc
    Par Débutant_ASM dans le forum Linux
    Réponses: 2
    Dernier message: 17/03/2010, 21h02
  2. assembleur inclu gcc
    Par J4e8a16n dans le forum Débuter
    Réponses: 3
    Dernier message: 27/03/2009, 19h26
  3. [boso kernel] Assembleur inline GCC - Undefined Reference
    Par Edouard Kaiser dans le forum Programmation d'OS
    Réponses: 13
    Dernier message: 29/07/2005, 09h24
  4. Une introduction à l'assembleur 80x86, 32 bits, GNU GCC
    Par pierre.jourlin dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 04/04/2005, 17h34
  5. Inserer de l'assembleur en c avec le compilateur gcc
    Par KORTA dans le forum Autres éditeurs
    Réponses: 9
    Dernier message: 20/08/2003, 03h19

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