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 :

Représentation en mémoire d'un char ** (à exploiter en assembleur)


Sujet :

C

  1. #1
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 944
    Points
    1 944
    Par défaut Représentation en mémoire d'un char ** (à exploiter en assembleur)
    bonjour,
    celle la je sais pas si je dois la placer dans asm ou C ou meme linux (vue que un utilise pas CDECL)
    je suis un peu confus avec un probleme.
    j'ai une fonction C (main) qui appelle une fonction asm(_pusher) qui a son tour appel un C(_affiche) et le retour de _affiche est renvoye a main.
    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
    38
    39
    40
    41
    #define _GNU_SOURCE
    #include <stdlib.h>
    #include <stdio.h>
     
    char * _pusher(int x,char **y);
    char * _Affiche(int a,char *s1,char *s2,char *s3);
    //------------- Main fucntion ---------------
    int main(int argc, char **argv)                                                                                                                                                                                                                                                
    {
     
        char **str = malloc(sizeof(char *) * 2);
        str[0] = malloc(sizeof(char) + 32);
        str[1] = malloc(sizeof(char) + 8);
        str[2] = malloc(sizeof(char) + 16);
        sprintf(str[0],"un");
        sprintf(str[1],"deux");
        sprintf(str[2],"trois");
     
        fprintf(stdout,"%p %p %p\n",str[0],str[1],str[2]);
        char *s = _pusher(3,str);
        fprintf(stdout,"From pusher : '%s'\n",s);
     
        free(s);
        free(str[0]);
        free(str[1]);
        free(str[2]);
        free(str);
        return EXIT_SUCCESS;
    }
     
    /*--------------------------------------------------------------------------------*/
    char * _Affiche(int a,char *s1,char *s2,char *s3)
    {
        char *str;
     
        fprintf(stdout,"in Affiche received %d str with total of %d parameter\n",a,a+1);
        fprintf(stdout,"%p %p %p\n",s1,s2,s3);
        asprintf(&str,"v = %s - %s - %s (%d)",s1,s2,s3,a);
     
        return str;
    }
    le code 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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    [CPU x64]
    [BITS 64]
     
    extern _Affiche
    global _pusher
     
    [SECTION .text]
     
    _pusher:
        push rbp      ;sauf rbp
        mov rbp,rsp ;prepare ma nouvelle stack car si j'ai plus de 6 parametre a envoyer vers _aff je vais devoir push 
     
        ;mov rdi,1      ;touche pas a rdi le premier parametre y estt
        mov rax,20h   
        add rsi,rax      ;rsi a le 2 eme parametre recu donc char ** je place a la position du premier char *
        mov rdx,rsi    ; je passe deuxieme  char * a rdx qui sera donc ....
        mov rax,20h
        add rdx,rax    
        mov rcx,rdx  ;je passe le 3eme char * a rcx 
        add rcx,rax
     
        call _Affiche       ;attention name mangling
     
        add rsp,24
     
        mov rsp,rbp
        pop rbp
        ret
     
    [SECTION .data]
     
    [SECTION .bss]
    la sortie ici a l'execution donne ceci:
    0xe54050 0xe54080 0xe540a0
    in Affiche received 3 str with total of 4 parameter
    0xe54050 0xe54070 0xe54090
    From pusher : 'v = un - - (3)'
    si je mets comme taille au niveau des mallocs pour s[0] 3, s[1] 5, et s[2] 16 j'ai :
    0xf9f050 0xf9f070 0xf9f090
    in Affiche received 3 str with total of 4 parameter
    0xf9f050 0xf9f070 0xf9f090
    From pusher : 'v = un - deux - trois (3)'
    Pour commencer on voit que je decalle rsi de 32 (0x20 ou 20h) c'est une premiere magouille car dans ma logique je devrais decaller de 8
    et donc la je ne comprend plus rien.
    je m'attend d'ai a avoir char **s donne &s[1] = &s[0] + 8, &s[2] = &s[1] + 8 ....
    mais la j'ai un truc qui depend de size dans malloc.

    ps : pour ce que ca interesse le pourquoi de tout ca, c'est pour contourner un probleme ou une fonction attend un nombre non determiner d'argument quand j'ai un tableau de charactere.
    une fonction dans le genre de vprintf. j'appelle donc mon code asm pour casser le tableau et envoyer les arguments a l'autre fonction.
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

  2. #2
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Points : 3 570
    Points
    3 570
    Par défaut
    Salut,

    je peux pas trop t'aider pour ta question, par contre la réponse m'intéresse.
    Juste un truc pour ton PS : même si j'ai pas tout compris au besoin, n'entre-t-on pas dans le cas d'utilisation d'une variadic list ?
    Plus je connais de langages, plus j'aime le C.

  3. #3
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 944
    Points
    1 944
    Par défaut
    Je t'explique le PS.
    en fait j'utilise et mon programe doit faire un pont entre une chaine de caractere et la fonction redisvCommand.
    donc j'ai en entree un string du genre
    zrange "ma cle avec des espaces" 1 10 WITHSCORE
    je la parse pour obtenir ceci
    char **txt = {"zrange","ma cle avec des espaces","1","10","WITHSCORE"}
    le probleme c'est que la fonction redisCommand agit comme printf en plus un je ne peux donc pas ajouter les txt[ i ] , je peux pas non plus passer directement la chaine de caractere a cause des espaces.
    donc je dois utiliser redisvCommand qui agit comme vprintf. il faut donc que je lui passe un va_list plutot qu'un char **.
    en ayant chercher on deconseille d'essayier de tranformer manuellement un char ** en va_list (#include <stdarg,h>)
    la macro va_start recuper les parametres dans la piles au debut de l'execution de la fonction.
    donc l'astuce est de passer manuellement tout les char * contenus dans le char ** a une fonction ce qui donnera pour fonction final ce ci
    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
    redisReply * _aff(redisContext * c,int count,...)
    {
        redisReply * reply = NULL;
        char *p;
        va_list ap;
        char *fmt = malloc(sizeof(char) * count * 3);
     
       sprintf(fmt,"\%s");
       p = fmt +2;
     
       for(i=1;i<count;++i;p+=3)
           sprintf(p," \%s");
     
        va_start(ap,fmt);
        reply = redisvCommand(c,fmt,ap);
        va_end(ap);
     
        free(fmt);
        return reply;
    }
    Pour le moment je suis bloque car je comprend pas comment m'assurer de retrouver tous les char* appartir de l'adresse qui est de le registre RSI.
    quand j'aurai la reponse a ma question je vais te poster le code ASM final si ca t'interesse toujours.
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

  4. #4
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour
    Il y a un hic dans votre code en assembleur, vous nous dite que l'on voit bien que vous décaliez RSI de 32 "(0x20 ou 20 h)" et que c'est une première magouille qui a pour but de faire un décalage de 8 bits selon votre logique. D'accord, mais voyez-vous, le problème avec les magouilles, c'est que cela ne fonctionne nécessairement pas.
    En assembleur, il y a des instructions qui permettent de réaliser des décalages ou rotation exemple sous des 64 bits: "ROL, ROR RCL, RCR" Alors pourquoi ne pas les utiliser tout simplement ( l'inconvenant c'est la perte définitive des valeur lorsque les bits arrivent au bit de poids fort ou celui du poids faible (de mémoire)).
    Personnellement, je n'ai pas compris l'intérêt de l'opération d'addition avec une instruction DOS du type 20h (terminaison) honnêtement.

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ce qui me paraît bizarre, c'est que tu sembles utiliser du code 64 bits mais avec la convention d'appel __cdecl, plutôt que la variante bizarre de __fastcall utilisée en x86-64...
    D'un autre côté, je me trompe peut-être, j'ai du mal à déchiffre ton code asm.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 944
    Points
    1 944
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Bonjour
    Il y a un hic dans votre code en assembleur, vous nous dite que l'on voit bien que vous décaliez RSI de 32 "(0x20 ou 20 h)" et que c'est une première magouille qui a pour but de faire un décalage de 8 bits selon votre logique.
    à bientôt
    alors, non c'est pas une magouille pour decaller de 32.
    voiila ce que j'ai fait dans un premier temps
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    mov rax,8
    add rsi,rax
    mov rdx,rsi
    add rdx,rax
    sauf que je me suis mes printf affichaient n'importe quoi.donc j'ai ajouter les printf pour voir les adresses et c'est la que je suis passe a 32. qui marche par fois et parfois pas.
    donc ma question est de savoir exactement ce que je dois faire pour retrouver l'adresse de chaque pointeur.
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

  7. #7
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 944
    Points
    1 944
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Ce qui me paraît bizarre, c'est que tu sembles utiliser du code 64 bits mais avec la convention d'appel __cdecl, plutôt que la variante bizarre de __fastcall utilisée en x86-64...
    D'un autre côté, je me trompe peut-être, j'ai du mal à déchiffre ton code asm.
    J'ai commente le code assembleur plus haut, tu peux le relire. non je n'utilise pas cdecl. le seul point commun c'est que je sauce rbp (ebp pour cdecl) et le restaure avant le ret.
    mais ca c'est pas propre a cdecl, la doc de l'ABI pour amd64 dit que dans call convention qu'il faut metre rdp dans le meme etat qu'on l'a trouver.
    avec cdecl j'aurait just push pour passer les parametres a _aff ici c'est claire si c'est type integer(int et variante, char, pointer) les 6 premiers parametres sont dans les registres et le reste on les push/pop
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

  8. #8
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    Ton code assembleur est hors sujet.
    L'addition des 0x20 que tu dois faire est due au fait que la fonction malloc utilise des cluster multiples de 32 octets!
    Ce que la fonction extrait, ce n'est pas les infos du tableau str[] mais directement la mémoire du heap! C'est pourquoi en changeant de taille allouée le comportement change.
    Je te propose :
    * append le langage C (ligne 11 on alloue 2 pointeurs, et on en utilise 3 à partir de là, tout est imprévisible)
    * trouve quelle est la convention d'appel imposée par ta fonction.
    * quel est le compilateur que tu utilises? Le C est puissant, la syntaxe en C pour forcer une convention d'appel dépend du compilateur.
    * écrire du code C qui respecte cette convention.
    * un jour ultérieur apprend l'assembleur.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    extern void __attribute__((fastcall)) fonction( int a , ... );
    void pusher( int a , char**str ) {
       fonction( a , str[0], str[1], str[2] );
    }

  9. #9
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 944
    Points
    1 944
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Bonjour,
    Ton code assembleur est hors sujet.
    L'addition des 0x20 que tu dois faire est due au fait que la fonction malloc utilise des cluster multiples de 32 octets!
    Ce que la fonction extrait, ce n'est pas les infos du tableau str[] mais directement la mémoire du heap! C'est pourquoi en changeant de taille allouée le comportement change.
    Merci c'est bon a savoir donc effectivement j'aurai jamais trouver
    Citation Envoyé par dalfab Voir le message
    Je te propose :
    * append le langage C (ligne 11 on alloue 2 pointeurs, et on en utilise 3 à partir de là, tout est imprévisible)
    Ce commentaire est tres hautain et tres peu necessaire. le 2 etait du a une fautre de frappe, je recopiais le code sur mon telephone car parfois ici je peux pas me connecter sur le site sans vpn mais mon telephone a le vpn en permence. ca tu pouvais pas le savoir mais tu pouvais te contenter de signaler l'erreur plutot que de me demander d'apprendre le C. j'avais meme oublie de taper les free(str[i])
    j'ai du editer. qu'aurais-tu dis si tu avais vu ca?
    Citation Envoyé par dalfab Voir le message
    * trouve quelle est la convention d'appel imposée par ta fonction.
    a chercher merci
    Citation Envoyé par dalfab Voir le message
    * quel est le compilateur que tu utilises? Le C est puissant, la syntaxe en C pour forcer une convention d'appel dépend du compilateur.
    j'utilise gcc, et je suis sous fedora 23 le systeme cible sera centos 7.
    Citation Envoyé par dalfab Voir le message
    * écrire du code C qui respecte cette convention.
    On va essayer
    Citation Envoyé par dalfab Voir le message
    * un jour ultérieur apprend l'assembleur.
    Ceci est aussi inutile, quand tu as des info utiles qui peuvent aider, je suis preneur et heureux de recevoir de l'aide, mais je me passe bien des jugements. si je savais tout je serai pas la a demander de l'aide
    Citation Envoyé par dalfab Voir le message
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    extern void __attribute__((fastcall)) fonction( int a , ... );
    void pusher( int a , char**str ) {
       fonction( a , str[0], str[1], str[2] );
    }
    le probleme ici est que je ne connais pas la valeur de 'a' avant l'execussion c'est pour ca que pusher est en assembleur. je mettrai les 6 premiers pointeurs dans les registres et le reste seront pusher.
    le nombre de pointeur n'est connu qu'a l'execusion et il n'est pas constant entre chaque appelle.

    mais je te remercie quand meme
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

  10. #10
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Excuse moi pour l'interprétation trop rapide du code C.
    Je voulais exprimer que selon moi, il devrait exister une solution purement en langage C.Je pense qu'il ne faut passer à l'assembleur que s'il le compilateur ne peut établir la correspondance (par exemple nommage ou format de passage non standard).
    Pour résoudre l'utilisation d'un nombre variable de paramètres, on peut le faire par un simple switch avec N cas prévus; et si le nombre est constant au point d'appel, on peut compter sur l'optimisation du compilateur
    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
    extern void __attribute__((stdcall)) fonction( int a , char* prem, ... );
    inline void pusher( int a , char**str ) {
       switch ( a ) {
          case 0:
          default:
          break;
          case 1:
             fonction( 1 , str[0] );
          break;
          case 2:
             fonction( 2 , str[0] , str[1] );
          break;
          ....
    }
    const int nb=2;
    pusher( nb , str ); // produira directement le code inline : fonction( 2 , str[0] , str[1] );
    c'est inélégant, mais à comparer à une procédure assembleur peut portable.

    Sinon en assembleur, d'après ton exemple, mon idée va vers
    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
    pusher:
       push rbp      ; standard stack frame
       mov rbp, rsp
     
       mov rax, rdi ; proteger rdi dans rax
       mov rdi, rsi
       mov rsi, [rdi] ; lecture t[0]
       mov rdx, [rdi+8] ; lecture t[1]
       mov rcx, [rdi+16] ; lecture t[2]
       mov r8, [rdi+24] ; lecture t[3]
       mov r9, [rdi+32] ; lecture t[4]
       ; au dela il faut passer par la pile
       mov rbx, [rdi+40] ; lecture t[5]
       push rbx
     
       mov rdi, rax ; retrouver rdi
     
       call _Affiche
     
       sub rsp, 8 ; restorer pile
       mov rsp, rbp
       pop rbp
    ret

  11. #11
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 944
    Points
    1 944
    Par défaut
    tu es pardonne, en fait quelqu'un qui vient presenter unprobleme et qui fait un malloc(2) et puis appelle le 3eme element ca fait tache
    je vais de ce pas tester ton code assembleur.
    le code C n'est pas utilisable car la variable count n'as pas officiellement de limite. comme j'ecris une API je peux forcer dans la donc mais meme en faisant ca
    l'utilisateur peux m'envoyer une enorme chaine une fois parser ca me donnera un truc genre tu conviendras qu'un switch ne m'aide que si je connais la limite et un switch de 256 c'est plus que pas elegent. il suffirait qu'on me mette 1 de plus et ca marche plus.

    en lisant ton code assembleur ton precedent commentaire prend tout sons sens
    Apprend l'assembleur
    je vois que j'avais pas bien compris comment recuperer l'adresse des pointeurs.


    Bon je viens de tester vite fais ton code ASM il est parfait je vais juste verifier que tout les cas marches bien et je mets ce sujet a resolut (je le fais pas toute suite car il me faut le temps de poster le code final ca interesse certain)
    Merci de ton aide elle m'a ete precieuse.
    la il est 2h du matin ou je suis, je le ferai donc demain ou lundi.
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    L'impossibilité de créer dynamiquement une va_list, c'est un des trucs que je reproche aux normes du C.
    J'avais fait un code avec un minimum d'asm pour profiter du DispInvoke() de Windows avec n'importe quelle fonction, mais ça nécessitait que Windows fasse le gros du travail et ça ne marchait qu'en 32 bits car je n'avais jamais fait de version x86-64...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 944
    Points
    1 944
    Par défaut
    C'est bien la une limit de la libc.
    en faite c'est possible de creer dinamiquement une va_list mais fortement deconseille pour des tas de raison. j'ai pas poursuivit dans ce sens mais il y avait un code en example bien commente.
    il existe une lib qui permet de faire ce que je veux faire mais avec certaine contrainte et j'ai d'ailleur oblie son nom.
    ca te tenterai bien de voir ton code meme si c'est destine a windows. histoire de m'instruire un peu
    bon la il faut vraiment que je dorme il est 3 heures la
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Mon code est à la fin de ce thread, qui contient une partie des réflexions qui y ont mené:
    http://www.developpez.net/forums/d43...dynamique-dll/

    Si j'avais le temps de my replonger, je supprimerais l'utilisation de TLS pour la version __cdecl en passant à la place à ma fonction de "forward" un pointeur vers une structure en variable locale de la fonction appelante, où je stockerais ce que je dois préserver. Oh, et je tenterais aussi de faire un code assembleur approprié pour la convention d'appel amd64 de Windows. Mais je n'ai pas ce temps ni cette énergie, hélas.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Bonjour,
    peut-être que la nouvelle bibliothèque jit de gcc peut faire l'affaire dans ces cas ?
    GCC jit.

  16. #16
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 944
    Points
    1 944
    Par défaut
    Bon c'est regle j'ai mis plus de temps parceque j'etais sur un autre projet et en plus il m'a fallut deasembler un code utilisant va_list pour voir pourquoi j'avais toujours segfault quand les parametre depassait 6 (seulement avec va_list)
    la reponse a cette question etait qu'il faut mettre ax a 0 (plus precisement al)

    donc voici le code C qui appelle pusher qui appellera redisCommand.
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    static char * getRedis(redisContext * c,const char *key,size_t *s_data)                                                                
    {   
        char *resp = NULL;                                                                                                                 
        char **args;                                                                                                                       
        size_t s;
        redisReply *reply;                                                                                                                 
        int count = 0;                                                                                                                     
        char *fmt;
        int i;
     
        args = argParser((char *)key,&count);                                                                                              
    //  fprintf(stderr,"cmd = '%s' (%d)\n",key,count);                                                                                     
     
        if(count < 0)                                                                                                                      
        {
            *s_data = 0;                                                                                                                   
            printf( "Error: command parsing error %d\n",count);                                                                            
            return NULL;
        }
     
        ALLOC(char ,fmt, (count * 3 ));                                                                                                    
        char *p;                                                                                                                           
        sprintf(fmt,"%%s");                                                                                                                
        p = fmt + 2;                                                                                                                       
     
        for(i=1; i<count; ++i, p+=3)                                                                                                       
            sprintf(p," %%s");                                                                                                             
     
        reply = _pusher(count,c,fmt,args);                                                                                                                                                                                                                                         
     
        for(i=0;i<count;++i)                                                                                                               
            free(args[i]);                                                                                                                 
     
        free(args);                                                                                                                        
     
        if(reply == NULL)                                                                                                                  
        {
            *s_data = 0;                                                                                                                   
            printf( "Error: Redis reply NULL\n");                                                                                          
            return NULL;                                                                                                                   
        }   
     
     
        if ( reply->type == REDIS_REPLY_ERROR )                                                                                            
        {   
            *s_data = 0;                                                                                                                   
            printf( "Error: %s\n", reply->str );                                                                                           
            return NULL;                                                                                                                   
        }   
     
        if(reply->type == REDIS_REPLY_STRING)                                                                                              
        {   
            if(reply->str != NULL)                                                                                                         
            {
                //s = 1 + strlen(reply->str) + 29;
                s = 1 + reply->len + 28;                                                                                                   
     
                ALLOC(char,resp,s);                                                                                                        
                sprintf(resp,"{\"type\":\"String\",\"value\":\"%s\"}",reply->str);                                                         
                freeReplyObject(reply);                                                                                                    
     
                *s_data = s - 1;                                                                                                           
                return resp;                                                                                                               
            }
        }
     
    ...
     return resp;
    et voici le code asm je le commanterai que si demande.(j'ai la flemme)
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    CPU x64]                                                                                                                                                                                                                                                                      
    [BITS 64]
     
    extern  redisCommand
    extern  aff
    global _pusher
     
     
    [SECTION .text]
     
    _pusher:
        push rbp
        ;push rbx
        mov rbp,rsp
     
        mov rax,rdi
        cmp rax,1
        je arg_1
     
        cmp rax,2
        je arg_2
     
        cmp rax,3
        je arg_3
     
        cmp rax,4
        je arg_4
     
        cmp rax,5
        jge arg_more
     
    arg_1:
        mov rax,rsi
        mov rsi,rdx
        mov rdi,rcx
        mov rdx,[rdi]
        mov rdi,rax
        jmp debut_appel
     
    arg_2:
        mov rax,rsi
        mov rsi,rdx
        mov rdi,rcx
        mov rdx,[rdi]
        mov rcx,[rdi + 8]
        mov rdi,rax
        jmp debut_appel
     
    arg_3:
        mov rax,rsi
        mov rsi,rdx
        mov rdi,rcx
        mov rdx,[rdi]
        mov rcx,[rdi + 0x8]
        mov r8,[rdi + 0x10]
        mov rdi,rax
        jmp debut_appel
     
    arg_4:
        mov rax,rsi
        mov rsi,rdx
        mov rdi,rcx
        mov rdx,[rdi]
        mov rcx,[rdi + 0x8]
        mov r8,[rdi + 0x10]
        mov r9,[rdi + 0x18]
        mov rdi,rax
        jmp debut_appel
     
    arg_more:
        mov rdi,rcx
        mov rcx,rax
        sub rcx,5
     
        ;debut de boucle
        loop_start:
            lea rax , [rcx * 0x8]
            mov rbx,[rdi + rax + 0x20]
            push rbx
            cmp rcx,0
            jle loop_end
            dec rcx
            jmp loop_start
        loop_end:
            mov rax,rsi
            mov rsi,rdx
            mov rdx,[rdi]
            mov rcx,[rdi + 0x8]
            mov r8,[rdi + 0x10]
            mov r9,[rdi + 0x18]
            mov rdi,rax
            xor rax,rax
     
    debut_appel:
        ;call aff
        call redisCommand
     
    _exit_:
        mov rsp,rbp
        pop rbp
     
        ret
     
    [SECTION .data]
    en esperant qu'il sera utile a qui ceux qui ont le meme probleme.
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Il faudra que tu trouves le temps de corriger argParser(), aussi.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 944
    Points
    1 944
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Il faudra que tu trouves le temps de corriger argParser(), aussi.
    Comment ca? je ne me souviens pas avoir poste le code du Parser? tu l'as vu ou?
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

  19. #19
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    J'en ai vu assez pour voir qu'il a besoin d'une correction:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    static char * getRedis(redisContext * c, const char *key, size_t *s_data)
    {
    	...
    	args = argParser((char *)key, &count);
    Soit argParser() ne modifie pas la chaîne et donc le pointeur devrait être déclaré const (ce qui fait que le cast ne serait plus nécessaire), soit il modifie la chaîne (façon strtok(), par exemple) et c'est getRedist() qui sevrait perdre son const, car c'est complètement stupide de mentir à l'appelant au sujet de modification de chaîne.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  20. #20
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 944
    Points
    1 944
    Par défaut
    Oui en effet, j'avais fait ca lors de mes tests pour me debarrasser des warnings et j'ai oublie de regler le probleme.
    Merci
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

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

Discussions similaires

  1. Taille mémoire: short VS char
    Par theodorandaipieds dans le forum Débuter
    Réponses: 21
    Dernier message: 18/05/2015, 19h56
  2. [RPG] Déroulement du jeu : comment le représenter en mémoire ?
    Par TheDrev dans le forum Développement 2D, 3D et Jeux
    Réponses: 1
    Dernier message: 31/08/2009, 20h20
  3. Stocker des données dans la mémoire pour exploitation sur feuilles excel
    Par newcodeur dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 16/09/2008, 12h03
  4. Représentation mémoire d'un CString
    Par alexadvance dans le forum MFC
    Réponses: 4
    Dernier message: 09/01/2008, 12h13
  5. [Tableaux] Exploitation de la mémoire avec PHP
    Par hackrobat dans le forum Langage
    Réponses: 9
    Dernier message: 24/05/2006, 17h26

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