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 :

MOV ESI, EDX


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Invité
    Invité(e)
    Par défaut MOV ESI, EDX
    Bonjour a tous, j'ai quelques soucis avec mon programme (nasm - 32 bits - linux), je voudrais afficher des entiers, donc je pense avoir compris le principe, mais après un moment de lute contre mon debugger, j'aimerais votre avis
    Voici mon 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
    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
    BITS 32
     
    section .data
    buff dd 10    
     
    section .text
    global main
     
    main:
     
    push ebp
    mov ebp, esp
     
    mov edi, buff  
    xor ecx, ecx   
    xor eax, eax
    mov al, 0
     
    remplir:               ; REMPLIR
    mov byte [edi], al    
    inc edi
    inc eax
    inc ecx
    cmp ecx, 10
    jne remplir
     
    mov eax, buff
    xor edx, edx
    xor esi, esi
     
    affiche_entier:                  ; AFFICHE L'ENTIER DANS EAX   
    mov ecx, 10
    div ecx
    cmp edx, 0
    je fin_affiche
    call affiche_chiffre
    jmp calcul
     
     
    end:                     ; END
    mov esp, ebp
    pop ebp
    mov eax, 0
    ret
     
    fin_affiche:              ; AFFICHE LE CHIFFRE DANS EAX(QUOTIENT)
    push eax
    push ebx
    push ecx
    push edx
     
    mov esi, [eax]          ; ICI JE PENSE QUE SA VA SEG_FAULT
    add byte [esi], 48
    mov eax, 4
    mov ebx, 1
    mov ecx, esi
    mov edx, 1
    int 0x80
     
    pop edx
    pop ecx
    pop ebx
    pop eax
    jmp end    
     
    affiche_chiffre:             ; AFFICHE LE CHIFFRE DANS EDX(RESTE)
    push eax
    push ebx
    push ecx
    push edx
     
    mov esi, [edx]             ; ICI SA SEG_FAULT
    add byte [esi], 48
    mov eax, 4
    mov ebx, 1
    mov ecx, esi
    mov edx, 1
    int 0x80
     
    pop edx
    pop ecx
    pop ebx
    pop eax
    ret
    Le soucis viens quand je veux passer mon chiffre de EDX (le reste) à ESI pour l'afficher.

  2. #2
    Membre confirmé Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    Mars 2008
    Messages
    314
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : Mars 2008
    Messages : 314
    Points : 550
    Points
    550
    Par défaut
    le sélecteur de segment n'as pas été initialisé dans ton code (registre ds), par contre aucune idée de ce qu'il faut faire exactement dans ton cas,car je ne programme pas pour linux

    note: j'avais l'intention de m'y mettre suite a cet article -> http://www.les-ziboux.rasama.org/elf-without-ld.html

  3. #3
    Membre éclairé
    Avatar de edfed
    Profil pro
    être humain
    Inscrit en
    Décembre 2007
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : Décembre 2007
    Messages : 476
    Points : 701
    Points
    701
    Billets dans le blog
    1
    Par défaut
    en regardantt vite fait le code, je vois qu'il est plein d'erreurs.

    le registre edx utilisé en index induit une page fault pour la simple raison qu'il contient le modulo de la division par 10, c'est à dire qu'il contient un chiffre entre 1 et 9
    evidement, il ne peut etre egal à 0 car un test sort de la conversion si il est egal à zero.
    ce qui est encore une erreur, la conversion s'arrete lorsque eax est egal à 0.

    le registre esi ici n'a aucune utilité.
    d'ailleur, les acces memoire sont completement inutile pour ce code.

    la conversion binaire vers decimal ascii se fait en divisant par 10 successivement, jusqu'à avoir un resultat à zero.
    le modulo contient le chiffre à sortir, à savoir un chiffre de poids faible, le chiffre des unités, suivit du chiffre des dizaines, etc...
    donc, l'ecran risque d'afficher le nombre à l'envers, les unités à gauche, les dizaines à droite.
    pour contrer ce malencontreux effet, il y a lieu alors d'utiliser la memoire, pour enregistrer les chiffres et les afficher dans le bon ordre, de gauche à droite.

    une combie simple consiste à utiliser la pile, ça gaspille un peu la ram, mais c'est très temporaire.

    empiler edx et incrementer ecx tant que eax est different de 0.
    depiler edx, afficher le caractère ascii égal à edx+'0' avec interrupt 80h tant que loop ecx different de zero.

    et voilà.

    en code, ça donnerait ça:
    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
     
    BITS 32
     
    section .data
    buff rb 1
     
    section .text
    global main
     
    main:
    mov eax,4567839
    call affiche_entier 
    xor eax,eax ;fin du programme si je me souvient bien.
    int 80h
     
    affiche_entier:                  ; AFFICHE L'ENTIER DANS EAX   
    ;eax=entier
    xor ecx,ecx ;init loop
    xor edx,edx ;cdq
    mov ebx, 10
    @@:
    div ebx
    push edx
    inc ecx
    or eax,eax
    jne @b
    @@:
    pop edx
    call affiche_chiffre
    loop @b
    ret 
     
    affiche_chiffre:             ; AFFICHE LE CHIFFRE DANS EDX(RESTE)
    push eax
    push ebx
    push ecx
    push edx
     
    mov ecx,buff ;on pointe sur buff, qui devient const void *buf
    mov eax, 4        ;ma foi, encore une fonction int80h de linux.
    ;4 STD POSIX { ssize_t write(int fd, const void *buf, size_t nbyte); }
    mov ebx, 1
    add dl,'0' ;ascii entre '0' et '9'
    mov [ecx],dl
    mov edx, 1
    int 80h
     
    pop edx
    pop ecx
    pop ebx
    pop eax
    ret
    voici un lien vers ce qu'on doit faire sous linux, la methode recommendée en somme.
    http://www.int80h.org/bsdasm/#system-calls

    je trouve dommage que l'on ne puisse pas utiliser la valeur d'un registre en tant que caractère au lieu de devoir utiliser une case mémoire.
    ça ralenti le systeme fortement de devoir faire ça. surtout si on peut s'en passer.

    à mon avis, en faisant pointer ds sur le meme segment que ss, il devrait etre possible de passer les caractères sans meme depiler edx.
    il suffirait de faire push edx, puis add esp,3 à chaque division pour n'empiler que les octets de poid faible (qui contienent le modulo entre 0 et 9). faire gaffe que ça ne genere pas de stack alignment fault.
    sinon, il faudra juste memoriser les differentes valeurs de edx sous la forme d'une chaine.
    enregistrer la taille de la chaine, puis l'afficher en une seule fois.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Merci a vous de vos réponses, en fait je sais bien que mon code n'est pas super, mais dans mes tests j'étais plus ou moins tombé sur ce problème que j'ai réglé entretemps. Donc pour l'instant mon code affiche mon nombre à l'envers :p Et je vais racourcir tout cela. Je reposte mon code après le boulot.

  5. #5
    Membre confirmé Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    Mars 2008
    Messages
    314
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : Mars 2008
    Messages : 314
    Points : 550
    Points
    550
    Par défaut
    aaaaaah! afficher un nombre! c'est un exellent exo pour un tout jeune programmateur assembleur

    voici ma réponse

    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
    mov ecx,10
    xor ebx,ebx
    boucle1:
    xor edx,edx
    div ecx
    add dl,"0"   ;(ou 48 la valeur ascii de zéro)
    push dx
    inc bx
    cmp eax,0
    jne boucle1
     
    boucle2:
    pop ax
    ;coller ici une procédure qui affiche le caractère dans al*
    dec bx
    jnz boucle2
    *je ne sais plus comment on fait chez dos ou nux mais chez moi c'est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    mov ah,7h ;la couleur
    int 84h

Discussions similaires

  1. video *.mov avec TMediaPlayer
    Par FredericB dans le forum C++Builder
    Réponses: 1
    Dernier message: 29/09/2006, 18h50
  2. ASM et C++ : problème avec un mov
    Par somebodyishere dans le forum Assembleur
    Réponses: 6
    Dernier message: 26/08/2006, 02h51
  3. Conversion à la volée de fichiers mov en swf
    Par Philoulheinz dans le forum Flash
    Réponses: 3
    Dernier message: 15/07/2006, 23h07
  4. Lecture MOV et DIVX
    Par jc44 dans le forum Applications et environnements graphiques
    Réponses: 3
    Dernier message: 10/01/2006, 17h09
  5. [ARM] Comment utiliser l'opération MOV
    Par maxliem dans le forum Autres architectures
    Réponses: 5
    Dernier message: 27/07/2005, 14h24

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