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 :

Interfaçage C - Assembleur


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Octobre 2006
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 11
    Par défaut Interfaçage C - Assembleur
    Bonjour,
    Etant débutant en assembleur (mais pas en langage C) je cherche pour des histoires de controle de flot d'execution un peu d'assembleur.
    Voila un des mes programmes de test qui ne fonctionne pas totalement.
    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
    22
    23
    24
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
     
    void works(){
    	printf("Mon adresse: 0x%08x\n",works);
    	printf("That works !\n");
    	__asm__("jmp ici");
    }
     
     
    int main(int argc, char** argv){
    	int a=0;
    	__asm__("xor %bx,%bx");
    	__asm__("jz	works");
    	__asm__("ici:");
     
    	printf("Si je suis le premier c'est perdu...\n");
     
    	printf("Ok\n");
    	printf("%i\n",a);
    	return EXIT_SUCCESS;
    }
    Cependant voici mon probleme. Lorsque je lance mon binaire, j'obtient la sortie suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Mon adresse: 0x080483f4
    That works !
    Si je suis le premier c'est perdu...
    Ok
    -1215659260
    Erreur de segmentation
    Merci de votre aide.

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Salut

    Voici comment une fonction telle que celle-ci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void hello(void)
    {
    	printf("hello !");
    }
    est assemblée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	push	ebp
    	mov	ebp, esp
    	sub	esp, 8
    	mov	DWORD PTR [esp], OFFSET FLAT:LC0
    	call	_printf
    	leave
    	ret
    En fait, EBP est la base de la pile et ESP la position courante (l'adresse où la prochaine valeur sera empilée). Lorsqu'on lance une fonction, elle créée son propre cadre de pile ; elle positionne ESP au niveau de la position courante. Mais pour ne pas perdre la valeur d'origine d'EBP, elle l'empile d'abord. Car une fois que la fonction se termine, le cadre de pile revient à son stade précédent. EBP doit donc revenir à sa valeur d'origine.
    Ceci est important pour bien structurer l'exécution d'un programme, pour y mettre les variables locales et l'adresse retour. Appeler une fonction, c'est comme empiler une assiette. Si une fonction appelle une fonction, qui appelle elle-même une fonction, c'est comme si on empilait deux assiettes sur la première assiette. Lorsqu'une fonction prend fin, on retire l'assiette qui se trouve au sommet, et le microprocesseur exécute l'instruction qui suit l'appel de la fonction (celle d'où l'on vient).
    Chaque assiette contient ses propres données : les données locales et l'adresse de retour.

    Dans ton programme, tu appelles la fonction par un "jz" (qui est un jmp conditionnel et non un appel) et dans la fonction appelée tu reviens dans celle d'origine par un "jmp". Du coup, les données dans la pile ne sont plus cohérentes, c'est comme si il y avait un décalage. Ton plantage est dû au fait qu'une mauvaise valeur est dépilée et correspond probablement à une adresse retour.

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 15
    Par défaut
    Lorsque une fonction C est lancé, elle se créé un cadre de pile. La cadre de pile de la fonction appelante est restitué lorsqu'un return est effectué, en faisant le "jmp ici", tu empêches la fonction de faire un return et donc de restituer le cadre de pile du main. Comme le C place les variables sur la pile et que le pointeur de pile n'est pas en bonne place au retour à ici, l'accès à a ne se fait pas au bon endroit d'où une erreur de segmentation.
    J'espère que ce raisonnement est juste, je ne suis pas un expert en assembleur.
    Bonne chance.

  4. #4
    Membre habitué
    Inscrit en
    Octobre 2006
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 11
    Par défaut
    Ok merci je vais tenter de voir comment je peux arranger ca. Merci pour ces réponses claires. C'est vrai que j'ai du mal a voir en assembleurs quels sont les registres que l'on peut manipuler sans crainte

  5. #5
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 81
    Par défaut
    Dans ce document sur l'Assembleur 8086, au chapitre 4 sur les sous-programmes (page 47), il y a le principe de fonctionnement expliqué en détail.

  6. #6
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 91
    Par défaut
    plutot qu'un "jz => jmp", pourquoi ne pas directement utiliser les instructions d'appel /retour ( call => ret) de l'assembleur ?
    Il me semble qu'avec ces instructions, tes registres sont modifiés tout seuls sans que tu n'ai a les toucher toi même.

  7. #7
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Citation Envoyé par Al_th
    Il me semble qu'avec ces instructions, tes registres sont modifiés tout seuls sans que tu n'ai a les toucher toi même.
    Pas tout seul ! il faut que la fonction appelées le fasse.
    Et s'il y a des paramètres de passé à la fonction,
    Selon la convention d'appel de la fonction, c'est soit la fonction appelée qui retir les paramètres de la pile (appel standard) soit au code qui appelle la fonction de le faire (appel C).

Discussions similaires

  1. Tutoriels, F.A.Q : la rubrique Assembleur de Developpez.com
    Par Alcatîz dans le forum Assembleur
    Réponses: 3
    Dernier message: 07/06/2007, 20h14
  2. [CR][ASP] interfaçage
    Par grosjej dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 15/04/2004, 11h20
  3. ecrire son OS (assembleur ??)
    Par Anonymous dans le forum Programmation d'OS
    Réponses: 9
    Dernier message: 25/11/2002, 20h25
  4. Random en Assembleur
    Par funx dans le forum Assembleur
    Réponses: 9
    Dernier message: 02/09/2002, 18h05
  5. Quel désassembleur/assembleur pour un exe Windows ?
    Par Anonymous dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 17/04/2002, 11h59

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