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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    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.

  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
    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 ?

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

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    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.

  4. #4
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    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 : 548
    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

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    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 extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    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

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

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    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.

+ 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