1. #1
    Membre régulier Avatar de awesomeman
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2015
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : octobre 2015
    Messages : 106
    Points : 87
    Points
    87

    Par défaut segfault sur un strlen en asm

    Bonjour,

    Je recode un strlen en asm qui est utilisé par la suite dans une librairie, j'utilise ensuite celle ci pour un code en c . Malheuresement, mon strlen segfault ...
    Le problème est peut etre lié à la compilation, mais je poste quand meme le code asm au cas ou .
    Voici chaque étape :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    nasm -o strlen.o strlen.S -f elf64                                // compilation 
    gcc -shared -o libasm.so strlen.o                                // génération de la lib pour le c 
    gcc -L/home/.../ect/.../dir/ -Wall -o test main.c -lasm          //  compilation de mon .c   ----> "me donne /usr/sbin/ld: attention: type et taille du symbole dynamique «strl» ne sont pas définis" (strl est le nom de ma funct asm) 
    ./test                                                           // j'execute le test de manière classique 
    et lorsque j'execute segfault :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     Process terminating with default action of signal 11 (SIGSEGV): dumping core
     Bad permissions for mapped region at address 0x601030
    code ASM:

    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
    [BITS 64]
     
    	global strl
    	section .text
     
    strl:
    	push rbp
    	mov rbp, rsp
     
            mov rdi, 0
    looop:	
    	cmp BYTE [rdi + rcx], 0
    	je fin
    	inc rcx
    	jmp looop
     
    fin:	
    	mov rax, rcx
    	mov rsp, rbp
    	pop rbp
     
    	ret
    code c :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main()
    {
      printf("%d", strl("zzzzzz"));
      return (0);
    }
    Merci pour votre aide !

    Bonne journée

  2. #2
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    .
    Inscrit en
    mai 2010
    Messages
    1 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : mai 2010
    Messages : 1 832
    Points : 4 830
    Points
    4 830

    Par défaut

    Ben regardant vite fait je me pose une question :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     mov rdi, 0
    looop:	
    	cmp BYTE [rdi + rcx], 0
    ok donc rdi = 0 , rcx il fait combien ? (s'il n'est pas initialisé le problème vient de la je pense).

    De plus [ rdi + rcx] ne sert a 'rien' a mon avis faudrait utilisé seulement un registre qui te sert de pointeur pas 2
    Je ne répond pas avec certitude je ne fais quasiment pas du x86 ^^'.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Technicien maintenance
    Inscrit en
    août 2011
    Messages
    6 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : août 2011
    Messages : 6 281
    Points : 12 956
    Points
    12 956

    Par défaut

    ok donc rdi = 0 , rcx il fait combien ? (s'il n'est pas initialisé le problème vient de la je pense).
    Tout à fait. Accéder à une adresse 0+un petit chiffre ne peut provoquer qu'un segfault. rdi devrait contenir l'adresse de la chaine dont la longueur devrait être calculé.

    sinon [rdi+rcx] est tout à fait valide en x86, mais aucun intérêt ici

    Je mettrais plutôt la chaine dans rsi et utiliserait lodsb (voir lodsw, lodsd pour des raisons de perfs) jusqu'à al=0. Il suffira ensuite de soustraire l'adresse d'esi.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur la création d'un système : http://chrtophe.developpez.com/tutoriels/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

  4. #4
    Membre régulier Avatar de awesomeman
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2015
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : octobre 2015
    Messages : 106
    Points : 87
    Points
    87

    Par défaut

    Oups en effet c'est rcx que je dois initialiser à 0 pas rdi

    Je mettrais plutôt la chaine dans rsi et utiliserait lodsb (voir lodsw, lodsd pour des raisons de perfs) jusqu'à al=0. Il suffira ensuite de soustraire l'adresse d'esi.
    Si je comprends bien, on mov rdi en rsi, ensuite on utilise lods pour "fusionner" rsi et rcx (ce qui permet de inc rsi ..?) et enfin on fait un rcx - rsi ?

    Merci pour vos réponses .

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Technicien maintenance
    Inscrit en
    août 2011
    Messages
    6 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : août 2011
    Messages : 6 281
    Points : 12 956
    Points
    12 956

    Par défaut

    mettre la chaine dans rsi permet d'utiliser le mnémonique lodsb qui va mettre l'octet présent dans rsi dans le registre al et incrémenter l'adresse de rsi.
    A optimiser de façon à utiliser les 64 bits de rax

    lodsb charge 1 octet depuis (e)si dans al
    lodsw charge 2 octets depuis (e)si dans ax
    lodsd charge 4 octets depuis esi dans eax
    lodsq charge 8 octets depuis rsi dans rax
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur la création d'un système : http://chrtophe.developpez.com/tutoriels/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

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

Discussions similaires

  1. Segfault sur un int?
    Par lguignar dans le forum C++
    Réponses: 9
    Dernier message: 18/07/2008, 10h03
  2. Segfault sur un int?
    Par lguignar dans le forum Débuter
    Réponses: 9
    Dernier message: 18/07/2008, 10h03
  3. Segfault sur contructeur de string
    Par lemmel dans le forum SL & STL
    Réponses: 7
    Dernier message: 02/09/2007, 13h50
  4. [Linux] StrLen en ASM
    Par Girzi dans le forum x86 32-bits / 64-bits
    Réponses: 2
    Dernier message: 17/07/2007, 10h59
  5. Renseignement sur les "types" d'asm
    Par Coussati dans le forum Assembleur
    Réponses: 4
    Dernier message: 10/01/2006, 14h28

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