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 :

[Débutant] Inversion d'une chaîne


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #21
    Invité
    Invité(e)
    Par défaut
    Change le dec ecx en sub ecx, 2 à la ligne 39 pour voir.

    Après étant donné que tu ajoutes la size de ton message, le zéro ne doit pas servir à grand-chose, sinon je ne peux pas dire comment marche ta fonction, je ne la connais pas

  2. #22
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    • ce n'est pas segment .code mais section .text qu'il faut spécifier
    • size n'est pas défini, il faut rajouter la ligne size equ $ - mesg pour que ça marche
    • ensuite tu fais un truc comme :
      Code nasm : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      push_chaine:
         mov eax, mesg
      pour ensuite comparer eax à 0 (la fin de la chaine de toute évidence), tu te mélange complètement les pinceaux
      ce que tu veux c'est prendre les caractères un par un, un caractère ASCII tient sur 8 bits, donc tu récupéreras dans un registre adéquat comme ah ou [/codeinline]al[/codeinline], et d'autre part ce n'est pas mesg mais son contenu !
      il faudra donc partir sur quelque chose du genre :
      Code nasm : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      push_chaine:
         mov al, [mesg]
    • comme dit plus avant ton code part en boucle infinie, tu incrémentes ecx mais tu ne l'utilises nulle part, pour finalement le remettre à 0 à la fin de la routine push_chaine, qui plus est le pointeur sur le message n'avance pas non plus du coup et tu ne push que la première lettre
    • d'ailleurs en parlant de ça, tu n'appelles tes deux sous-routines qu'une seule fois chacune, tu pourrais très bien faire un programme linéaire tout en prenant soin de sauter une ligne dans ton code pour aérer, ce serait largement suffisant
    • quant à pop_chaine elle ne sert simplement à rien, comme tu push caractère par caractère, le message final se retrouve à l'envers sur la stack, il suffit de l'afficher tel quel en faisant un truc du style sys_write(0, esp, size-1)
    • oui parceque - dernier point - quand tu invoques le syscall write en début de code, tu mets mov ecx, mesg, hors mesg lui n'a pas changé du tout, vu que tu as fais tes modifications sur la pile


    maintenant et sans vouloir relancer la polémique, utiliser push ici va compliquer les choses, étant donné qu'on ne peut pas pousser directement un registre 8 bits
    une manière de contourner les choses pourrait être de traiter les caractères du message 4 par 4, on met tout dans eax, on inverse en jonglant un peu et on push
    Code nasm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    mov eax, [msg + ecx]  ; "Salu"
    xchg ah, al           ; "aSlu"
    rol eax, 16           ; "luaS"
    xchg ah, al           ; "ulaS"
    inc ecx, 4
    sauf que du coup pour tester la fin du message on ne pourra plus se contenter d'un simple cmp avec la valeur 0, sur lequel des quatre octets tombera le nulchar ?

    on pourrait alors se lancer dans des checks systématique sur chacun des groupes de 8bits de eax pour voir si on a détecté le 0

    une solution peut-être un peu plus astucieuse consiste à calculer notre coup en jouant avec une division et l'alignement sur la pile; on divise la taille du message à afficher par 4, on a d'un coté le quotient (dans eax) et de l'autre le reste (dans edx)
    on va boucler autant de fois qu'il le faut pour traiter tout le message (boucle sur le quotient), quitte à déborder un peu de quelques octets, et au moment d'afficher (quand on charge ecx pour le syscall) on rectifiera en ajoutant le reste de la division pour afficher juste ce qu'il faut, sachant que comme on aura renversé les octets dans eax, si le reste vaut 0 il faudra ajouter 4, si il vaut 1 il faudra ajouter 3 etc.

    à l'arrivée ça donne un truc comme ça :
    Code nasm : 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
     
    section .text
    global _start
     
    _start:
        mov eax, size
        mov ebx, 4
        div ebx             ; quotient dans EAX, reste dans EDX
     
        xor edx, 3          ; leger trick pour permettre l'alignement plus tard sur la pile vu qu'on renverse les valeurs
                            ; si edx = 0  -->  0 xor 3 = 3 octets a rajouter pour aligner sur la pile
                            ; si edx = 1  -->  1 xor 3 = 2 octets a rajouter pour aligner sur la pile
                            ; si edx = 2  -->  2 xor 3 = 1 octets a rajouter pour aligner sur la pile
                            ; si edx = 3  -->  3 xor 3 = 0 octets a rajouter pour aligner sur la pile
        inc edx
        mov ecx, edx        ; on sauve edx dans ecx temporairement
        mul ebx             ; resultat dans EAX:EDX
        mov edx, ecx        ; on remet edx comme ca nous arrangeait
        xor ecx, ecx        ; on met ecx à 0
        mov ebx, eax        ; on sauve eax dans ebx
     
    ; note: à ce stade EBX contient donc le quotient de la division multiplié par 4,
    ; et EDX contient 4 moins le reste de la division pour pouvoir aligner
    ; donc si le message fait 13 octets de long, EBX vaut 16 et EDX vaut 3
     
    boucle:
        mov eax, [mesg+ecx]         ; on lit 4 octets
        xchg ah, al                 ; ---
        rol eax, 16                 ; on les renverse
        xchg ah, al                 ; ---
        push eax                    ; et on pousse fort
        add ecx, 4                  ; on incremente ecx de 4 du coup
        cmp ecx, ebx                ; et on compare avec notre ebx sauvé au début (le quotient de la division)
        jbe boucle                  ; on jump si "inférieur ou égal" ou "pas supérieur" (JBE equ JNA)
     
        mov eax, 4                  ; sys_write()   ( grep -r __NR_write /usr/include/, man 2 write )
        mov ebx, 1                  ; 1 == STDOUT_FILENO    ( /usr/include/unistd.h )
        mov ecx, esp                ; le message a l'envers, stocké sur la pile
        add ecx, edx                ; on ajoute le reste de la division, pour alignement (voir plus haut)
        mov edx, size               ; la taille
        int 80h                     ; syscall gate
     
        mov eax, 1                  ; sys_exit()    ( grep -r __NR_exit /usr/include/, man 2 exit )
        mov ebx, 0                  ; code de retour == 0
        int 80h                     ; syscall gate
     
    section .data
        mesg db 'Salut les potes'   ; note : on a fait sauter le nulchar qui ne servait à rien du coup
        size equ $ - mesg

    ça marche... mais on s'est pas mal emmerdé la vie quand même faut bien admettre
    d'un autre côté la solution sans push sur la pile :
    Code nasm : 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
    section .text
    global _start
     
    _start:
        mov ebp, esp    ; le prologue, classique
        sub esp, size   ; on reserve SIZE octets sur la pile
     
        mov ecx, size
        mov esi, mesg+size-1                                                                                                                                                                                                                   
        mov edi, esp
    boucle:
        mov al, [esi]   ; on récupère les caractères en partant du dernier
        mov [edi], al   ; on les stocke sur la pile un par un en commençant par le sommet de la pile
        dec esi         ; pointeur source : on va vers le 1er caractère (de droite à gauche)
        inc edi         ; pointeur destination : on continue d'avancer sur la pile (de gauche à droite)
        loopnz boucle   ; jusqu'à ce que ecx == 0
     
        ; on affiche
        mov eax, 4
        mov ebx, 1
        mov ecx, esp
        mov edx, size
        int 0x80
     
        ; on quitte
        mov eax, 1
        mov ebx, 0
        int 0x80
     
    section .data
        mesg db 'Salut les potes'
        size equ $ - mesg
    c'est quand même plus simple et plus clair à lire non ?

  3. #23
    Invité
    Invité(e)
    Par défaut
    "ce n'est pas segment .code mais section .text qu'il faut spécifier"
    Nommer une section code marche aussi, pour mon projet HackEngine il en est ainsi par exemple et je trouve code plus précis que text, perso.

    Pourquoi la polémique sur push/pop ?
    On est d'accord que la majorité des programmeurs asm les détestent.

    Sinon pour le coup de récupérer une donnée 8 et non 32 sur msg m'a échappé, voilà la correction, mais toujours pas tester: http://www.developpez.net/forums/d15...e/#post8385613
    Dernière modification par Invité ; 21/09/2015 à 11h13.

  4. #24
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Pourquoi l'utilisation de la pile pose problème ?...
    Je dirais que ça fait faire de la gymnastique, et que c'est théoriquement plus lent qu'un "mov reg2,reg1"

    Venant du Forth, j'ai l'habitude de cette gymnastique (bien qu'il n'y ait aucun outil évolué en asm)
    de plus, ça permet d'éviter d'avoir des variables à déclarer pour chaque sauvegarde de registre

    Bien sûr, il faut peser le pour et le contre, s'il faut utiliser 20 octets de code pour éviter de définir une variable de 2 octets ...

    Dans l'exemple ici, il est clair que ce n'est pas la bonne solution, mais si c'est un exercice sur l'utilisation de la pile, faut bien faire avec

  5. #25
    Invité
    Invité(e)
    Par défaut
    Essaye de peser le pour/contre dans ce code, parce que bon je ne me vois pas utiliser push/pop dans ce cas (chouia complexe):
    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
     
            %macro      memclr      2
           ;{
                ;==============================================================================================================.
                ; Name    : memclr (ptr dest, ptr limit)                                                                       |
                ; Purpose : Clear all buffer's content untill reach pointer's limit.                                           |
                ; Input   : dest - limit                                                                                       |
                ; Output  : [dest]                                                                                             |
                ; Destoy  : None                                                                                               |
                ; Data    : Stack                                                                                              |
                ; Define  :                                                                                                    |
                            %define    STACK_PARAM      (2 * E64)                                   ; dest/limit               |
                            %define    STACK_REG        (2 * E64) + (1 * E8) + (1 * E256)           ; rdi/rcx + al + ymm0      |
                            %define    STACK_SIZE       (STACK_PARAM + STACK_REG)                                             ;|
                ;                                                                                                             ;|
                            %define    DEST             (rsp - STACK_SIZE) + (E64 * 0)                                        ;|
                            %define    LIMIT            (rsp - STACK_SIZE) + (E64 * 1)                                        ;|
                ;                                                                                                             ;|
                            %define    REG1             (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 0)                          ;|
                            %define    REG2             (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 1)                          ;|
                            %define    REG3             (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 2) + (E8 * 0)               ;|
                            %define    REG4             (rsp - STACK_SIZE) + STACK_PARAM + (E64 * 2) + (E8 * 1) + (E256 * 0)  ;|
                ;==============================================================================================================.
               ;{
                    ; Store function's reg in stack
                        mov         [REG1], rdi
                        mov         [REG2], rcx
                        mov         [REG3], al
                        vmovups     [REG4], ymm0
     
                    ; Store function's param in stack
                        m2m         [DEST ], %1, rdi
                        m2m         [LIMIT], %2, rdi
     
                    ; Store function's param in function's reg
                        mov         rdi, [DEST]
                        mov         rcx, [LIMIT]
                        vxorpd      ymm0, ymm0, ymm0        ; For white screen 
                        ; vpxor       ymm0, ymm0, ymm0        ; Need avx2
                        ; vmovups     ymm0, [ps_infinit]      ; For the fun, look like freak game due to "random" color equal to texture
     
                    ; Function's core
                        %push   memclr
                        %ifctx  memclr
                       ;{
                            sub     rcx, E256 - 1       ; For data corrupt protect due to avx padding.
                           ;{
                                %$1:
                               ;{
                                    vmovups     [rdi], ymm0
     
                                    add     rdi, E256
                               ;}
                                jif  rdi ,<=, rcx, %$1
                           ;}
                            add     rcx, E256 - 1        ; Restore origin address
     
                            ; Do 1 byte move loop, for fill end memory
                                dec     rdi         ; for avoid to do if(rdi <= rcx) before stosb
                                xor     al, al
     
                                %$2:
                               ;{
                                    stosb           ; [rdi++] = al
                               ;}
                                jif  rdi ,<=, rcx, %$2
                       ;}
                        %endif
     
                    ; Retore function's reg
                        mov         rdi , [REG1]
                        mov         rcx , [REG2]
                        mov         al  , [REG3]
                        vmovups     ymm0, [REG4]
               ;}
                ;===================================================================================================.
                ; / memclr                                                                                          |
                ;===================================================================================================.
           ;}
            %endmacro
    Dernière modification par Invité ; 21/09/2015 à 11h44.

  6. #26
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par shaynox Voir le message
    Nommer une section code marche aussi (...) et je trouve code plus précis que text, perso.
    ça n'est pas la même chose, il ne t'aura pas échappé qu'il s'agit d'un code pour linux (passage des paramètres au syscall dans les registres, int 80h...), la section qui contient le code exécutable s'appelle .text et est définie par l'ABI System V, on aurait aussi pu l'appeller .saucisse mais ce n'est pas ce qui a été retenu
    sauf erreur, ce doit être le linker (ld) qui attribue automatiquement les droits qui vont bien aux sections ELF spéciales comme .text ou .data
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ readelf -S executable_.* | awk '/1\]/ || NR == 6 || and(NR+1,254) == 30'
      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 1] .code             PROGBITS        08048074 000074 000039 00   A  0   0  1
      [ 1] .text             PROGBITS        08048080 000080 000039 00  AX  0   0 16
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings)
    quant à section ou segment les deux directives sont équivalentes, c'est juste une question de cohérence puisque dans son code il met section .data.

  7. #27
    Invité
    Invité(e)
    Par défaut
    Mais apparemment remplacer text par code pour cette section marche aussi sur Linux, donc apparemment pas de stresse à avoir ^^

    Donc même si c'est normaliser, tant que cela marche, osef de cette norme bidon
    Dernière modification par Invité ; 21/09/2015 à 21h01.

  8. #28
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    tu as raison shaynox, comme toujours.

  9. #29
    Invité
    Invité(e)
    Par défaut
    Bah sans doute, si l'OP n'a pas de problème lors de la compilation et de l'exécution.

    Enfin si cela te gêne tellement, parle en a l'OP de tes craintes :/

  10. #30
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par shaynox Voir le message
    Bah sans doute, si l'OP n'a pas de problème lors de la compilation et de l'exécution.
    Enfin si cela te gêne tellement, parle en a l'OP de tes craintes :/
    j'explique 3 posts plus haut qu'une section .text et une section .code ne seront pas équivalentes, puisque les deux n'ont pas les mêmes droits d'accès, la section nommée .text est reconnue comme étant une section spéciale 1 2, là dessus tu viens pour expliquer que c'est pas grave alors que tu n'utilises même pas Linux, non seulement c'est au minimum présomptueux de ta part mais ça induit également Adboulito en erreur, à l'arrivée ça donne une intervention que l'on qualifiera en bon français d'impertinente, ce qu'on pourrait largement dépasser si c'était tout à fait ponctuel mais non, c'est permanent avec toi shaynox, et à la longue c'est vraiment pénible.

  11. #31
    Invité
    Invité(e)
    Par défaut
    Pense ce que tu veux, cela ne va pas m'empêcher d'aider l'auteur.

    Si tu as une envie d'aider l'auteur au point d'essayer de vouloir rabaisser les autres, abstinent toi d'écrire la prochaine fois, cela ne fait que du mal à la communauté française des programmeurs, déjà bien pauvres en esprit mature.
    Dernière modification par Obsidian ; 21/09/2015 à 22h52. Motif: Amendement sur proposition de l'auteur.

  12. #32
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Shaynox, faut vraiment que t'arrêtes de penser que les gens te prennent de haut quand ils te corrigent.
    Comme je l'avais écrit, je trouve ça super que tu sois là pour aider les débutants, mais il faut grandir un peu...

  13. #33
    Invité
    Invité(e)
    Par défaut
    Quand ils me corrigent ? d'où ils me corrigent ?

    Ce que j'avance dans mes messages ne sont que le fruit de mon expérience et ce sont de bons fruits



    Alors qu'on essaye de corriger ma recette, moi je dis non, voyer en moi comme un vieux programmeur têtu si vous voulez un cliché et ne faites pas semblant qu'il n'y ait que moi qui à ce genre de personnalité.
    Eh oui, à peine deux d'apprentissage et de codage en asm et me voilà déjà rentrer dans la catégorie de vieux programmeurs grognon, ouais, mais apparemment j'ai de bonnes raisons pour l'être, voyez par vous-même avec la suite.

    Après est-ce que j'accepte la critique ? Bien sûr que j'en accepte, j'en ai déjà accepté d'ailleurs dans le passé (enfin que sur des forums internationaux, à croire que les Français sont des quiches en social skill ), sauf qu'il faut respecter certains critères pour qu'il en soit ainsi, désolé :/
    Quels sont ces critères ? Bah déjà sur un sujet intéressent et intelligent (parce que l'histoire du nommage de la section, euh cela m'a tout l'air d'une histoire à deux sous dans les cours de récré), sans laisser sous-entendre qu'on prenne de haut et j'en oublie certainement.


    Et comme vous l'avez vu deux fois sur ce sujet, si on ne respecte pas les règles avec moi, enfin avec moi, cela doit tout aussi être valables pour tout le monde
    Alors si on ne respecte pas, on a droit en retour à un joli retour de bâton amplifié.

    Si je n'ai pas envie de faire un debug traditionnel, cela me regarde
    Si je n'ai pas envie d'utiliser push/pop , cela me regarde
    Si je n'ai pas envie de nommer une section text, cela me regarde
    ;...

    Après si vous n'êtes pas d'accord à ce que j'encourage l'OP d'emprunter ma voix, je m'en fous, faites-lui seulement part de vos idées vous aussi.
    Pas la peine de rentrer en désaccord avec le voisin qui essaye d'aider l'OP, ce n'est pas très malin en plus, parce que si vous vous confrontez avec un esprit aussi têtu que moi, vous déviez le sujet.


    Après l'OP décidera de lui-même, en même temps cela lui offrira d'autres possibilités, comme de la concurrence, mais ce n’est vraiment pas la peine d'essayer de rabaisser la concurrence.
    Et puis même si c'est un débutant, il a forcément son propre système de jugement, ne croyez-vous pas ? Si vous avez peur qu'un gars comme moi l'écoute de A à Z, faites-lui simplement confiance pour qu'il ne le fasse pas ^^ tout en l'aidant gentiment sans être tenter de mordre l'autre candidat qui essaye de l'aider.

    Vous imaginer s'ils font pareil dans les pubs sur un même produit ? En visant une marque précise ? Ça doit se faire, mais très rarement.


    Et à propos du nommage de la section code, je le répète, si l'OP n'a pas de problème lors de la compilation et de l'exécution, alors o.s.e.f !!!!
    Est-ce si complexe à le comprendre ?
    Après s'il rencontre un quelconque problème dans le futur, et bien ok, qu'il mette .text à la place, mais pour l'instant, go passer à un autre problème plus intéressent, comme ... bah il n'a pas redonné de nouvelles depuis, donc on attente au lieu de s'enflammer pour des trucs inutiles.


    Wow, qui aurait cru que déclencher des disputes sur le net (ne pas sous-entendre que c'est moi qui les déclenche, merci d'avance), puis les analyser pouvait améliorer l'analyse de l'être humain, fantastique
    Après le challenge c'est de savoir si on n’est pas contre cela finalement



    D'ailleurs, veuillez me pardonner pour ce qui va suivre, mais c'est bien la première fois que l'on vient m'emmerder pendant que j'aide quelqu'un dans un topic asm (même quand j'étais sur OC), enfin avec kannagi, ce n'était pas la même chose, car ce n’était pas des choses techniques comme traiter ici présent.

    J'espère juste que l'on va me lâcher la grappe pour les futures fois où j'aiderais quelqu'un, car critique non, on n’est pas là pour essayer d'aider son voisin, mais pour aider l'OP et personne d'autres, alors inutiles d'essayer de prouver par A + B que le voisin a tord, car il s'en fout, juste dire son autre solution à l'auteur du topic.
    Dernière modification par Invité ; 24/09/2015 à 22h31.

  14. #34
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 451
    Points : 43 097
    Points
    43 097
    Par défaut
    BufferBob, shaynox,

    Sous Linux, il est d'usage de procéder comme cela :

    section.text
    GLOBAL _start:
    ...
    ...

    section .data
    ...
    ...
    _start étant le point d'entrée pour le linker.

    J'ai essayé avec le code suivant :

    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
     
    section .text
    global _start
    _start:
    mov eax,4
    mov ebx,1
    mov ecx,chaine
    mov edx,chaine_fin - chaine
    int 0x80
    mov eax,1
    int 0x80
     
    SEGMENT .data
     
    chaine : db"hello world",0
    chaine_fin :
    compilé ainsi :
    nasm -f elf test.asm
    gcc -nostdlib test.o -o test

    Cela fonctionne.

    J'ai ensuite remplacé section.text par section .code, cela compile et fonctionne toujours.
    l'utilisation de objdump -x fait bien apparaitre la section nommée .code, nasm ne change pas le nom.

    Si je remplace section .code par segment.code (et sans même mettre segment .data) cela fonctionne toujours.

    Utiliser section ou segment est identique. La documentation nasm : http://www.nasm.us/doc/nasmdoc6.html précise au point 6.3 que segment et section sont identiques. .code n'est par contre pas une section standard du format elf,le standard étant .text pour le code.
    Sous le format elf utilisé par Linux, il me semble même qu'il est possible de supprimer les informations de sections avec des elf kickers sans empêcher le code de se charger, mais attention , je suis pas sûr à 100 %.

    Par ailleurs si on utilise la fonction gcc -S, permetant de voir le code assembleur d'un source C, on verra une section .text et .data.

    Je pense que code segment / data segment est plutôt utilisé en environnement Windows.

    Si je prends la page : https://fr.wikipedia.org/wiki/Portab...e_des_Sections concernant le format PE utilisé par Windows,
    il parle de .text, et pas vraiment de .code, mais il présice aussi que le nom n'est pas significatif.
    J'ai par contre toujours vu sous Windows l'utilisation de segment code et segment data. dans les sources.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  15. #35
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par chrtophe Voir le message
    J'ai ensuite remplacé section.text par section .code, cela compile et fonctionne toujours.
    oui, je ne me l'explique pas -encore ;p- d'ailleurs, car si .text est reconnue par le linker comme étant une section spéciale devant avoir des droits spécifiques il n'est est pas de même pour une section .toto ou .code, un objdump -h -j .text/.code permet de se rendre compte que les droits sur la plage mémoire ne sont pas les mêmes, notamment qu'une section nommée .code n'a pas de droits d'exécution, en toute logique le code ne devrait pas pouvoir s'exécuter
    à minima on peut constater la différence avec un coup de gdb, avec une section .code on ne peut pas désassembler apparemment

    il me semble même qu'il est possible de supprimer les informations de sections avec des elf kickers sans empêcher le code de se charger, mais attention , je suis pas sûr à 100 %.
    oui c'est le propos de l'utilitaire sstrip, mais les droits des sections eux ne sont pas supprimés par contre

    Je pense que code segment / data segment est plutôt utilisé en environnement Windows.
    c'est tout le problème, utiliser le terme de "segment" induit en erreur puisqu'effectivement Linux n'utilise pas les segments de code et de donnée (les registres CS et DS) pour cloisonner, en ce sens les sections d'un binaire n'ont rien à voir avec la segmentation, mais après tout les deux directives sont équivalentes, il s'agissait plus d'une question de cohérence ici (voir plus haut)

    par contre la question du .code sans les droits d'exécution et qui permet d'exécuter du code malgré tout me pose + question, à titre personnel, que shaynox soit d'accord ou pas je m'en bats l'oeil par contre, j'ai compris qu'il n'y a pas de solution heureuse et que loin d'être un comportement voulu c'est plus certainement subi et irrépressible, j'ai pas particulièrement de solution hormis ignorer. je pense pas que ce soit utile de revenir là dessus en revanche.

  16. #36
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2015
    Messages : 14
    Points : 26
    Points
    26
    Par défaut
    C'est encore moi !

    Les codes proposés par Bufferbob fonctionnent, et mieux, je les comprends. En fait va surtout falloir que je prenne l'habitude de faire les choses méthodiquement, il n'y avait rien de très compliqué mais j'ai l'impression qu'en asm encore plus que dans les langages de haut niveau, si on part dans tous les sens c'est perdu d'avance. Par contre, je me demandais, l'utilisation de esi & edi (qui semble logique vus les noms de ces registres) était surtout là pour gagner en clarté c'est ça ?

    Je compte réécrire le programme en passant par des variables en mémoire, et aussi prendre la valeur de la chaîne via l'entrée standard. A ce sujet j'ai une question : quand on récupère la chaine de caractères, est-ce qu'une zone mémoire lui est allouée et le pointeur est stocké dans edx, ou alors la chaine est simplement mise dans le registre ?

    Désolé de pas être repassé avant, j'ai repris les cours. Et merci de prendre le temps de m'aider (et de vous engueuler )

  17. #37
    Invité
    Invité(e)
    Par défaut
    Et sinon tu as testé mon code que j'ai update hier soir ?
    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
     
     
    global _start
     
    segment .code
    ;{
        _start:
       ;{
            jmp     push_chaine
            fin_push_chaine:
     
            jmp     pop_chaine
            fin_pop_chaine:
     
            mov     ecx, msg
            mov     eax, 4              ; syscall 4 = stdout(ecx)
            mov     ebx, 1
            mov     edx, size
            int     80h                 ; stdout msg
     
            mov     eax,1               ; Interruption linux
            mov     ebx,0               ; Pour quitter
            int     80h                 ; Le programme
       ;}
     
        push_chaine:
       ;{
            xor     ecx, ecx
            loop1:
           ;{
                dec     esp
                mov     al, [msg + ecx]
                mov     [esp], al
     
                inc     ecx
           ;}
            cmp     al, 0               ; Quand fin chaine on arrete de boucler (faute de frappe corriger)
            jne     loop1
     
            dec     ecx                 ; Si le zéro n'est pas pris en compte, alors mettre sub     ecx, 2 pour voir
       ;}
        jmp     fin_push_chaine
     
        pop_chaine:
       ;{
            xor     ebx, ebx
            loop2:
           ;{
                mov     al, [esp]
                mov     [msg + ebx], al
                inc     esp
     
                inc     ebx
           ;}
            loop     loop2              ; While (ecx)
       ;}
        jmp     fin_pop_chaine
    ;}
     
    section .data
        msg:    db  "Salut les potes", 0
    (On voit la jalousie là )

    "quand on récupère la chaine de caractères, est-ce qu'une zone mémoire lui est allouée et le pointeur est stocké dans edx, ou alors la chaine est simplement mise dans le registre ?
    "

    Pas trop compris, si tu fais un mov edx, msg, tu récupères l'adresse de msg, si tu fais un mov edx, [msg], tu récupères 4 octets partant de msg.

    Après si tu parles de la meilleure technique, à toi de voir, perso je ferais ta transformation à l'aide que de registres et de ta chaine de caractère.
    Dernière modification par Invité ; 22/09/2015 à 11h45.

  18. #38
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2015
    Messages : 14
    Points : 26
    Points
    26
    Par défaut
    Pour stdin, c'est juste moi qui aie lu la doc de travers donc rien à signaler au final. Je n'ai pas mentionné ton code car les deux se ressemblent beaucoup au final, même si le tient est plus proche de ce que je pensais faire au départ mais plus long. Par contre ligne 39 t'as fait une faute de frappe, c'est al et pas am.

    Je ne vois pas quelle technique est la meilleure, mais ce que je sais c'est qu'on m'a assez rabaché qu'on n'apprenait que par la pratique pour que j'applique le conseil.

  19. #39
    Invité
    Invité(e)
    Par défaut
    HAHA première fois que je fais une faute de frappe et que je ne la vois pas immédiatement quand je tape du code asm, bon en même temps je suis dans une position qui n'est pas trop adaptée à l'écriture ...

    Sinon pour l'histoire des techniques, forge-toi tes propres techniques, demande conseil, mais fait quand même appel à ton imagination aussi.

    Certains pourront réagir très mal à ce que j'ai dit, car c'est anti-éducation (école), bon alors j'anticipe.

    À tout ce qui voudront me prouver de A à Z que j'ai tord, passer vos chemins et dites simplement à Abdoulito qu'il faut suivre (comme un mouton ) les techniques traditionnels selon vous, dites pourquoi vous faites ce choix, mais sans être tenté de m'adresser la parole et faire une quelconque référence à shaynox.

    Merci d'avance

  20. #40
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2015
    Messages : 14
    Points : 26
    Points
    26
    Par défaut
    Ayant travaillé et travaillant encore sur des projets à plusieurs, je trouve quand même que, s'il faut une dose d'imagination, un peu de formalisme ne fait pas de mal quand il s'agit de travailler ensemble, sinon ça devient vite à s'arracher les cheveux pour pas grand chose.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. Inversion d'une chaîne de caractères
    Par camoa dans le forum x86 16-bits
    Réponses: 7
    Dernier message: 31/10/2011, 13h56
  2. Réponses: 3
    Dernier message: 26/05/2010, 23h39
  3. Inversion d'une chaîne
    Par Maxence45 dans le forum Pascal
    Réponses: 36
    Dernier message: 14/03/2007, 23h58
  4. [Débutant] Comment sauvegarder une chaîne ?
    Par nmqm dans le forum Assembleur
    Réponses: 1
    Dernier message: 28/02/2006, 23h49

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