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 :

[NASM] elf64 recode memset


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 30
    Points : 33
    Points
    33
    Par défaut [NASM] elf64 recode memset
    Hello, j'ai un petit problème ! Je ne comprends pas pourquoi mon memset ne fonctionne pas. Si quelqu'un pouvais m'aider !

    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
    $>cat run; echo '---main.c---' && cat main.c && echo '---my_memset.S--' && cat my_memset.S
    #!/bin/sh
    gcc -c main.c -g3 && nasm -f elf64 -o tmp.o -g3 my_memset.S && gcc main.o tmp.o && ./a.out && rm -f tmp.o main.o
    ---main.c---
    #include <stdio.h>
    #include <stdlib.h>
     
     
    void *my_memset(void *s, int c, size_t n);
     
    int		main(int ac, char **av)
    {
      int		*tab;
      int		idx;
     
      tab = malloc(sizeof(*tab) * 10);
      idx = 0;
      while (idx < 10)
        tab[idx++] = idx;
      printf("tab = %p\n", tab);
      idx = -1;
      while (++idx < 10)
        printf("tab[%i] = %i\n", idx, tab[idx]);
      printf("my_memset(tab, 42, 10) = %p\n", my_memset(tab, 42, 10));
      idx = -1;
      while (++idx < 10)
        printf("tab[%i] = %i\n", idx, tab[idx]);
      return 0;
    }
    ---my_memset.S--
    [BITS 64]
     
    global my_memset
     
    section .text
     
    ; void* memset(void *s, int c, size_t n)
    ;		rdi      rsi    rdx
     
     
    my_memset:
      push rbp		; prologue
      mov rbp, rsp
     
      xor rcx, rcx		; compteur
    .while:
      cmp rcx, rdx		; while rcx != rdx
      je .endwhile
     
      mov [rdi+rcx], rsi	; remplissage
      inc rcx		; incrementation du compteur
     
      jmp .while
     
    .endwhile:
      mov rax, rdi		; valeur de retour
     
      mov rsp,rbp		; epilogue
      pop rbp
      ret
    D'avance merci.
    PS : la sortie est
    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
    tab = 0x600a60
    tab[0] = 0
    tab[1] = 1
    tab[2] = 2
    tab[3] = 3
    tab[4] = 4
    tab[5] = 5
    tab[6] = 6
    tab[7] = 7
    tab[8] = 8
    tab[9] = 9
    my_memset(tab, 42, 10) = 0x600a60
    tab[0] = 707406378
    tab[1] = 707406378
    tab[2] = 10794
    tab[3] = 0
    tab[4] = 0
    tab[5] = 5
    tab[6] = 6
    tab[7] = 7
    tab[8] = 8
    tab[9] = 9

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Bonjour,

    Ton memset fonctionne : « 42 » s'écrit « 0x2a » en hexadécimal et « 0x2a2a2a2a » (sur 32 bits, donc) s'écrit « 707406378 » en décimal. C'est bien la valeur que tu obtiens.

    Les problèmes sont que :
    • Ta fonction remplit n octets alors que tu lui passes l'adresse d'un tableau de n pointeurs (quatre à huit fois plus longs, sur des machines 32 ou 64 bits respectivement) ;
    • Tu n'initialises pas tes registres en début de procédure. Ça « tombe en marche » ici mais en fonction du contexte et des options d'optimisation que tu passes à ton compilo, il peut en aller complètement différemment.


    Au niveau de l'adressage, plus précisément, tu écris bien « RSI » en mémoire, mais le mode d'adressage indirect que tu calcules donne toujours une adresse mémoire, avec une granularité d'un octet donc, contrairement à l'arithmétique des pointeurs du langage C dont l'adresse renvoyée, elle, tient compte de la taille de l'objet pointé.

    En outre, un registre RSI initialisé à 42 contient donc « 00 00 00 00 00 00 00 2a » en hexadécimal. Compte tenu de l'endianess des Intel, les valeurs écrites en mémoire seront « 2a 00 00 00 00 00 00 00 ». En décalant cela d'un octet à la fois, seul l'octet le plus à gauche demeure. Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    2a 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    2a 2a 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    2a 2a 2a 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    2a 2a 2a 2a 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    2a 2a 2a 2a 2a 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    …

Discussions similaires

  1. Recherche tutorial NASM Linux
    Par camje_lemon dans le forum Assembleur
    Réponses: 2
    Dernier message: 19/11/2004, 23h42
  2. [NASM] Utiliser des fichiers ressources
    Par trax44 dans le forum Assembleur
    Réponses: 8
    Dernier message: 26/09/2004, 18h42
  3. [NASM] Ligne de commande
    Par sirozz dans le forum Assembleur
    Réponses: 1
    Dernier message: 23/08/2004, 19h31
  4. [Linux] [NASM] Entrée de chaines
    Par vi4ever dans le forum Assembleur
    Réponses: 4
    Dernier message: 27/07/2004, 21h28
  5. [NASM] Redirection de l'interruption 09h
    Par sirozz dans le forum Assembleur
    Réponses: 2
    Dernier message: 16/07/2004, 17h32

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