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 :

Probleme valeur retour fonction


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut Probleme valeur retour fonction
    Bonjour,

    Je debute l'assembleur x86 et je tente de recoder quelque fonction de la lib c pour me faire la main. Mais je rencontre quelque probleme concernant la valeur de retour de ma fonction (ci-dessous isprint).
    La fonction ci-dessous me retourne un chiffre aleatoire du style 16384.
    Quelqu'un voit-il le probleme?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    global _isprint
     
    _isprint:	xor		eax, eax
    			cmp		edi, 20h ; SPACE
    			jl		no
    			cmp		edi, 7Eh ; ~
    			jg		no
    			mov		eax, 1
    no:			ret
    Merci d'avance,

  2. #2
    Invité
    Invité(e)
    Par défaut
    Salut, essaye avec jb (jl) et ja (jg) pour voir.

    ja/jb pour des nombre non signée et jg/jl pour nombres signés.

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    cmp    a, b
       Jump              Meaning               Signedness (S or U)
    .-----------------------------------------------------------.
    | je     |      Jump if (a =  b )         |                 |
    | jz     |      Jump if (a =  b )         |                 |
    | jne    |      Jump if (a != b )         |                 |
    | jnz    |      Jump if (a != b )         |                 |
    | ja     |      Jump if (a >  b )         |        U        |
    | jg     |      Jump if (a >  b )         |        S        |
    | jnle   |      Jump if (a >  b )         |        S        |
    | jae    |      Jump if (a >= b )         |        U        |
    | jge    |      Jump if (a >= b )         |        S        |
    | jnl    |      Jump if (a >= b )         |        S        |
    | jb     |      Jump if (a <  b )         |        U        |
    | jnae   |      Jump if (a <  b )         |        U        |
    | jl     |      Jump if (a <  b )         |        S        |
    | jnge   |      Jump if (a <  b )         |        S        |
    | jbe    |      Jump if (a <= b )         |        U        |
    | jna    |      Jump if (a <= b )         |        U        |
    | jle    |      Jump if (a <= b )         |        S        |
    | jng    |      Jump if (a <= b )         |        S        |
    | jecxz  |      Jump if (ecx =  0)        |                 |
    | jcxz   |      Jump if (cx  =  0)        |                 |
    | jncx   |      Jump if (cx  != 0)        |                 |
    | jmp    |      Unconditional jump        |                 |
    | jc     |      Jump if Carry             |                 |
    | jnc    |      Jump if Not Carry         |                 |
    | jo     |      Jump if Overflow          |                 |
    | jno    |      Jump if Not Overflow      |                 |
    | jp     |      Jump if Parity            |                 |
    | jpe    |      Jump if Parity Even       |                 |
    | jpo    |      Jump if Parity Odd        |                 |
    | jnp    |      Jump if Not Parity        |                 |
    | js     |      Jump if signed            |                 |
    | jns    |      Jump if Not signed        |                 |
    .-----------------------------------------------------------.
    Dernière modification par Invité ; 05/05/2015 à 20h47.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    Cela ne change rien :s

  4. #4
    Invité
    Invité(e)
    Par défaut
    Il y a quoi dans edi ?

    Si ce n'est qu'un caractère à analyser, alors tu dois prendre le registre dil (8 bit).

    Et garde le ja/jb system, car dans la table ascii, c'est de 0 à 255.
    Dernière modification par Invité ; 05/05/2015 à 21h05.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    edi contient le caractere a tester

    Je ne vois pas pourquoi dil ?
    edi es un registre d'offset, il contient donc (dans mon cas) l'addresse du caractere recut en parametre (arreter moi si je dit des betises)

  6. #6
    Invité
    Invité(e)
    Par défaut
    Il contien l'adresse ? ah désolé j'ai cru qu'il contenait le caractere.

    Donc il faut faire [edi] pour dire que la valeur utiliser est un pointeur, au cpu ^^

    Le fait qu'on dise qu'edi est un registre d'offset, c'est juste une des multiples defintions de registres qu'intel à dicter.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    apres verification, je dit n importe quoi, edi contient bien 1 caractere.

    Sinon pour revenir a mon probleme, le souci ne vient pas des cmp, mais du return de ma fonction. Si je commente les cmp et les ja/jb, il me renvois toujours un chifre bizarre, c'est eax qui ne prend pas la valeur 1.
    eax contient le return de la fonction.

    la tous va bien eax vau bien 0 au return
    mais avec cette ligne eax ne vau pas 1 comme il devrait.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Hmm je vois un global dans ta fonction, donc tu veux linker ta fonction asm dans un autre langage ?

    Pour ça que tu rencontres des difficultés, car le compilateur peut très bien modifier le registre eax avant que le printf ne s'exécute, tu devrais sauvegarde le registre eax dans une variable, puis l'afficher.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    Oui le but final es de refaire certaine focntion de la librairie c en asm (donc au final une librairie).

    Je vien d'essayer de passer par une variable cela n'as aucun impact.
    Je ne comprent pas pourquoi sa ne marche pas, le retour d'une fonction s effectue bien comme sa? (en mettant la valeur dans eax)

  10. #10
    Invité
    Invité(e)
    Par défaut
    Pour le standard du C oui et peut-être bien pour les autres.

    Hmm peux-tu me passer le code qui affiche eax ?

    Ou simplement tu link tout le code asm qui contient cette fonction et le code en syntaxe intel :p

  11. #11
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    Code de test pourtant tres simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <stdio.h>
     
    int      isprint(int c);
     
    int		main(void)
    {
    	int		tmp;
     
    	tmp = isprint('A');
    	printf("%d\n", tmp);
    	return (0);
    }

  12. #12
    Invité
    Invité(e)
    Par défaut
    Je vois et maintenant tu affiches l'asm file (gcc: -S -masm=intel)

    Et ... comme tu travailles en 32 bit, la norme d'envoie de paramètres dans les fonctions se fait par la pile et non par les registres, la seul norme qui les utilise est en mode x64:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    rcx        ; parameter 1
    rdx        ; parameter 2
    r8         ; parameter 3
    r9d        ; parameter 4
     
    Ensuite, c'est au tour de la pile de jouer son rôle d'envoie de paramètre.
    Pour windows c'est le cas, après pour Linux c'est le même principe mais different registre.

    Tu peut essayer de remplacer edi par [esp], mais pour en etre sûr, c'est mieux d'avoir l'asm file produit par tout ton code.
    Dernière modification par Invité ; 05/05/2015 à 23h29.

  13. #13
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    comme tu travaille en 32 bit, la norme d'envoie de parameter dans les function se font par la pile et non par les registres, la seul norme qu'il les utilisent sont en mode 64:
    sa dois surement venir de sa, je vais creuser de ce coter.
    A moins que tu ne sache comment gerer les parametres et le retour d'une fonction en 32 bit.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Le retour d'une fonction en 32 et le même que pour le 64, par contre l'envoie des paramètres est gérée par la pile (esp), mais envoie le fichier asm produit par tout le code pour voir stp ^^

  15. #15
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    envoie le fichier asm produit par tout le code pour voir stp
    le binaire?

  16. #16
    Invité
    Invité(e)
    Par défaut
    euh oui mais sous forme asm

    Si tu as gcc, tu rajoute -S -masm=intel dans les options du compile.

  17. #17
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    Si tu as gcc, tu rajoute -S -masm=intel dans les options du compile.
    Connaisait pas sa, merci pour l'astuce

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    	.file	"main.c"
    	.intel_syntax noprefix
    	.section	.rodata
    .LC0:
    	.string	"%d\n"
    	.text
    	.globl	main
    	.type	main, @function
    main:
    .LFB0:
    	.cfi_startproc
    	push	ebp
    	.cfi_def_cfa_offset 8
    	.cfi_offset 5, -8
    	mov	ebp, esp
    	.cfi_def_cfa_register 5
    	and	esp, -16
    	sub	esp, 32
    	mov	DWORD PTR [esp], 65
    	call	isprint
    	mov	DWORD PTR [esp+28], eax
    	mov	eax, DWORD PTR [esp+28]
    	mov	DWORD PTR [esp+4], eax
    	mov	DWORD PTR [esp], OFFSET FLAT:.LC0
    	call	printf
    	mov	eax, 0
    	leave
    	.cfi_restore 5
    	.cfi_def_cfa 4, 4
    	ret
    	.cfi_endproc
    .LFE0:
    	.size	main, .-main
    	.ident	"GCC: (Debian 4.7.2-5) 4.7.2"
    	.section	.note.GNU-stack,"",@progbits
    pourrais-tu m expliquer un peu ce fichier?
    (je n ai encore jamais vu la plupart des ligne: .cfi_def_cfa_offset )
    merci d'avance si tu prend le temps

  18. #18
    Invité
    Invité(e)
    Par défaut
    Np, oublie ces phrases bizarre, perso ça me donne des boutons de les voir, pour ça que j'ai migré MS compiler/intel compiler qui ont une bien meilleur présentation de l'asm file ^^


    Bien, alors primo, voici le nouvel asm simplifié (et optimisé ):
    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
     
    .globl  main
    .section    .rodata         ; Section nommé .rodata (ecrit en raw dans le binaire) pour aider l'OS a démarrer ton exécutable (.data pour moi)
        .LC0:   .string "%d\n"  ; data
    .text                       ; Section .text qui contient ton code, perso je l'appelle .code
        main:
            ; soustrait 32 bytes a esp pour faire une déclaration de 32 octets en mémoire pour ce petit bout de code
            ;  qui sera délimité par (esp - 32) et (esp)
            sub     esp, 32
     
                    mov     [esp], dword 65         ; 65(ascii) = A(ascii)
                call    isprint
     
                    mov     [esp    ], dword .LC0   ; printf.string
                    mov     [esp + 4], eax          ; printf.param#1
                call    printf
     
                mov     eax, 0                      ; Return 0
     
            add     esp, 32                         ; Rend l'espace alloué à la pile.
     
        ret
    Comme tu voit gcc envoie la letter A (65) dans la pile ([esp]), ensuite il store la valeur de retour (eax) dans la pile de printf pour pouvoir l'afficher.

    Donc voilà, il suffit de remplacer edi par [esp], et ça marcheras.
    Dernière modification par Invité ; 06/05/2015 à 05h18.

  19. #19
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    Merci mais, tu es a coter de mon probleme.
    Tu cherche sur les conditions cmp alors que mon probleme et sur le retour de isprint.

    Pour illustrer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    global _isprint
     
    _isprint:	xor		eax, eax
    ;			cmp		edi, 20h ; SPACE
    ;			jb		short no
    ;			cmp		edi, 7Eh ; ~
    ;			ja		short no
    			mov		eax, 1
    no:			ret
    me retourne 16384 au lieux de 1

  20. #20
    Invité
    Invité(e)
    Par défaut
    Normal qu'il ne sorte pas 1, vu que tous les tests sont faux, donc ça jump au label no, et donc ton mov eax, 1 n'est pas executer par ton proc (pour ton premier problème)

    Ensuite c'est pas possible que ça te sorte autre que 1 si tu met en comment, ok donc on va faire un truc, remplace ton code par lui et execute le pour voir:
    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
     
    global _isprint
     
    _isprint:
            xor     eax, eax
     
            cmp     [esp], byte ' '
            jb      no
     
            cmp     [esp], byte '~'
            ja      no
     
            or      eax, 1      ; = mov    eax, 1
            no:
    ret

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. concat probleme valeur retour
    Par fasyr dans le forum Requêtes
    Réponses: 3
    Dernier message: 15/05/2012, 14h04
  2. traiter valeurs retour fonction explode
    Par ju0123456789 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 21/05/2010, 11h25
  3. Réponses: 7
    Dernier message: 10/09/2009, 15h00
  4. [HTML] Probleme valeur de retour checkbox
    Par krony dans le forum Balisage (X)HTML et validation W3C
    Réponses: 8
    Dernier message: 29/11/2005, 14h59
  5. Probleme valeur de parametre dans une fonction
    Par TitouLolo dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 19/05/2005, 13h56

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