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 :

[MASM32][Débutant] Coder un strlen


Sujet :

x86 32-bits / 64-bits Assembleur

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2009
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2009
    Messages : 5
    Par défaut [MASM32][Débutant] Coder un strlen
    Bonjour à tous,

    Je suis débutant dans ce langage.

    Je ne saisis pas tout xD, je ne vois pas à quoi servent les registres, comment traiter des chaînes de caractères genre strlen en asm.

    J'ai essayé de faire strlen, donc la chaîne se termine par 0 comme en C, mais faut-il que je declare un int comme compteur ou je dois-je utiliser un registre, registre compteur => ECX, et je peux traiter ma chaîne directement avec szString ? Ou je dois la copier dans un registre ?

    Voilà le code :
    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
    .386
    .model flat,stdcall
    option casemap:none
    ;include \masm32\include\windows.inc
    ;include \masm32\include\user32.inc
    ;include \masm32\include\kernel32.inc
    ;includelib \masm32\lib\user32.lib
    ;includelib \masm32\lib\kernel32.lib
     
     
    .data
     
    szString  db "toto",0
     
    .code
     
           start:
     
                    push ebp            ; Declaration ebp
                    mov ebp, esp        ; Copie esp dans ebp
                    mov esi, szString    ; Recupere l'argv0 et le Copie ebp+8 dans esi
                    mov ecx, 0          ; Copie 0 dans ecx
     
            boucle:
                    mov al, [esi]       ; Copie valeur de esi dans al
                    cmp al, 0           ; Compare 0 a al
                    je fin              ; Jump if Equal a fin
                    add ecx, 1          ; ecx = ecx + 1
                    add esi, 1          ; esi = esi + 1
                    jmp boucle          ; Saut inconditionnel au label
     
            fin:
                    mov eax, ecx        ; Copie ecx dans eax
                    mov esp, ebp        ; restor esp
                    pop ebp             ; Supprime ebp
                    ret
     
    end start
    Merci pour votre aide

  2. #2
    Membre expérimenté

    Inscrit en
    Février 2009
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 200
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    mov edi LP.String
    mov ecx 0-1
    mov al 0          ; Recherche de EOS (string zero ended)
    repne scasb
    mov eax 0-2
    sub eax ecx      ; Eax = Nombre de caractères dans ta string

  3. #3
    Membre régulier
    Inscrit en
    Août 2009
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 12
    Par défaut
    Voilà un de mes codes (FASM) qui pourrait t'être utile :
    (note : j'ai gardé la partie qui t'intéresse pour éviter toute confusion)

    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
     
    format PE console 4.0
    include 'win32a.inc'
    entry start
     
     
    section ".data" data readable writeable
     
              [...]
              String  db 'azerty',0
     
    section ".code" code readable executable
     
            start:
     
                 cld
                 mov edi, String
                 xor ecx, ecx
                 dec ecx
                 xor eax, eax
                 repne scasb
                 not ecx
                 dec ecx     
    [..]
    Explications :

    1. cld : Clear D. Le Flag D est mit à zéro. Ce flag indique au µproc la direction à suivre pour parcourir, par exemple, une chaine de caractères. En le mettant à zéro le pointeur de chaine, EDI, sera incrémenté de façon automatique. Si au contraire tu souhaites décrémenter, et donc changer ton sens de parcours, tu peux utiliser setd.
    2. mov edi, String : La chaine de caractère est placée dans le registre EDI.


    Viens ensuite la partie suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
                 xor ecx, ecx
                 dec ecx
                 xor eax, eax
                 repne scasb
                 not ecx
                 dec ecx
    En détails :
    1. xor ecx, ecx : ECX est mit à zéro.
    2. dec ecx : ECX est décrémenté. C'est notre compteur. ECX = longueur de la chaine+1 (je t'explique d'où vient le +1 par la suite).
    3. xor eax, eax : EAX = 0.
    4. repne scasb: Recherche le zéro de fin de chaine. Tant qu'il boucle EDI est incrémenté ("a", "z", "e" puis "r", etc jusqu'au "0" de fin de chaine), et ECX lui est décrémenté comme on l'a vu au début de ce bloc.

      Valeurs successives de ECX :
      0xFFFFFFFF -1
      0xFFFFFFFE -2
      0xFFFFFFFD -3
      etc...

    5. not ecx : On a des valeurs négatives. Or la taille d'une chaine est positive donc on utilise l'instruction not pour passer en positif. On exécute ici un complément à 1. Voir ici.
    6. dec ecx : La valeur contenue dans ECX contient la taille de notre chaine+1. Pourquoi +1 ? Et bien le 0 de fin de chaine a été compté, on décrémente alors ECX pour arriver à la valeur correcte.


    Au final ECX contient la longueur de ta chaine.
    Il y a bien des moyens pour arriver à faire ce que tu désires. Je t'en donne juste un exemple.

    ntrl

  4. #4
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 193
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    invoke strlen,addr szString
    Le résultat est retourné dans eax.

  5. #5
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2009
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2009
    Messages : 5
    Par défaut
    Je vous remercie de votre aide =D.

    Tout est bien explique, je commence a comprendre.

    Mais est on oblige de copier la chaine de charactere dans le registre EDI (Destination index), ou on peut la "traiter" directement ?


    Merci encore pour votre aide.

  6. #6
    Membre expérimenté

    Inscrit en
    Février 2009
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 200
    Par défaut
    La traiter "directement" reviendrait à faire une série de tests et d'accès mémoire plus lents.
    En assembleur x86 ce sont les registres edi/esi qui sont utilisés pour le traitement des chaînes et ecx comme compteur.
    Ce sont des conventions et non pas des choix laissés à ta discrétion
    Ce système permet d'utiliser les répétitions rapides et les caches µp de manières efficaces.

Discussions similaires

  1. Réponses: 1
    Dernier message: 10/08/2009, 07h43
  2. [MASM32][Débutant] Read / Write Console
    Par Jean Michou dans le forum x86 32-bits / 64-bits
    Réponses: 7
    Dernier message: 16/04/2008, 23h24
  3. [MASM32][Débutant] Comment linker ?
    Par Gavroche7 dans le forum x86 32-bits / 64-bits
    Réponses: 8
    Dernier message: 09/02/2008, 16h48
  4. [Débutant][Simulink] HDL Coder
    Par safrout dans le forum MATLAB
    Réponses: 2
    Dernier message: 28/05/2007, 12h44
  5. [MASM32][Débutant] Erreur de compilation
    Par Priest dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 02/10/2005, 02h06

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