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 16-bits Assembleur Discussion :

[8086] Parcourir un tableau à l'envers dans une pile


Sujet :

x86 16-bits Assembleur

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 11
    Points : 8
    Points
    8
    Par défaut [8086] Parcourir un tableau à l'envers dans une pile
    Bonjour,

    je ne sais pas si le titre du message est clair. Je dois créer une procédure qui inverse la position des lettres dans un mot. Mais pour faire çan je dois parcourir un tableau « à l'endroit » et celui où je range les caractères, je dois le parcourir à l'envers.

    J'ai déjà dû créer une procédure qui enlevait les espaces dans une phrase.
    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
    EFFACE_ESPACE  PROC far
     
    PUSH BP
    MOV BP,SP
    MOV SI,[BP+8]
    MOV DI,[BP+6]
    MOV CX, CAR1
     
    boucle3:
      MOV AL,[SI]
      CMP AL,0020H
      JE cas_suivant
      JNE ajout
    ajout:
      MOV [DI],AL
      INC DI
    cas_suivant:
      INC SI
    LOOP boucle3
     
    POP BP
    ret 4
    endp
     
    PROGRAMME PRINCIPAL
     
    LEA BX, MESS_ENTREE
    PUSH BX
    LEA BX, MESS_SANS_ESPACE
    PUSH BX
    CALL EFFACE_ESPACE
    LEA DX,MES_SANS_ESPACE
    CALL OUTPUT_MESSAGE

    Cependant, je ne comprends pas tout dans la procédure. On nous a un peu donné la réponse. J'ai un peu du mal à voir la différence entre SI, DI et [SI], [DI]. [BP+x] sont les adresses de l'emplacement des PUSH ?

    DONC : Comment parcourir un tableau à l'envers sachant qu'il est dans une pile? Une âme charitable pourrait-elle me détailler les interactions avec la pile ?

    Je vous remercie d'avance.

    PC; Machine virtuelle XP SP3 32bits, sous Seven 64bits, E8400 3GHz
    TASM + TD

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 360
    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 360
    Points : 23 600
    Points
    23 600
    Par défaut
    Bonjour,

    Citation Envoyé par Biloy Voir le message
    J'ai un peu du mal à voir la différence entre SI, DI et [SI], [DI]. [BP+x] sont les adresses de l'emplacement des PUSH ?
    Tous les registres fonctionnent plus ou moins de la même façon, et sont capables de rendre à peu près les mêmes services, à ceci près que plusieurs d'entre eux sont utilisés par les différentes opérations du processeur, et ne sont donc pas interchangeables à ce niveau. Par exemple, CX est utilisé comme compteur par l'instruction LOOP, même si tu peux obtenir le même résultat avec « DEC registre; JNZ etiquette ».

    SI et DI signifient « Source Index » et « Destination Index ». Ils peuvent également être utilisés à n'importe quoi mais c'est eux que les instructions STOS LODS et MOVS exploitent. Il est donc d'usage d'utiliser les mêmes registres lorsque l'on fait des manipulations de chaîne à la main même si ce n'est pas obligatoire.

    Pour répondre à ta question, « registre » se réfère au registre lui-même et « [registre] » se réfère à l'adresse en mémoire pointée par le registre. Par exemple :

    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        MOV BX,8000h            ; Charge la valeur 8000h dans BX
     
        MOV word ptr [BX],1234h ; Dépose la valeur 1234h en 8000h-8001h

    La pile, elle, est pointée par SS:SP (Stack Segment et Stack Pointer). Chaque fois que tu fais PUSH, le registre « SP » est décrémenté de la taille de ce que tu veux empiler, et cet élément est sauvé en mémoire à l'endroit alors pointé par SP.

    Lorsque tu fais POP, c'est l'inverse : la valeur est chargée depuis l'endroit pointé par SP, puis celui-ci est incrémenté de la taille de l'élément dépilé.

    DONC : Comment parcourir un tableau à l'envers sachant qu'il est dans une pile? Une âme charitable pourrait-elle me détailler les interactions avec la pile ?
    Une pile est, par définition, une structure LIFO (Last In First Out), comme une pile d'assiettes : le premier élément empilé est le dernier dépilé : on comprend ainsi qu'en empilant une suite d'éléments, ceux-ci sont de fait stockés « à l'envers » dans la pile. Il suffit donc d'empiler une à une toutes les lettres de ton mot, puis d'aller les lire directement dans la pile à l'endroit pointé par SP.

  3. #3
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    Citation Envoyé par Biloy Voir le message
    J'ai un peu du mal à voir la différence entre SI, DI et [SI], [DI].
    SI et DI sont des registres. Utilisés avec l'instructions MOV cela permet de récupèrer la valeur des registres ou alors de mettre la valeur du registre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MOV SI, 42          ; SI = 42 (met la valeur de SI à 42)
    MOV AX, SI          ; AX = SI = 42 (récupère la valeur de SI, soit 42)
    [SI] indique que ce que contient (la valeur de) SI est un pointeur. SI par exemple SI vaut 100:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MOV AX, [SI]          ; AX = la valeur (d'un taille de 16 bits) à l'adresse 100.
    [BP+x] sont les adresses de l'emplacement des PUSH ?
    [BP+x] permet de récupérer les arguments de la fonction.

    DONC : Comment parcourir un tableau à l'envers sachant qu'il est dans une pile? Une âme charitable pourrait-elle me détailler les interactions avec la pile ?
    Partons du principe que dans ta fonction qui met à l'envers une chaine:

    - SI pointe sur le buffer source: la chaine de caractères à renverser. Elle est terminée par un octet à 0.

    - DI pointe sur le buffer destination: la chaîne renversée y sera stockée.

    0) Sauve SI (adresse du début de la chaine). Sauve DI (adresse du buffer destination).

    1) Calcule la longueur de la chaine pointée par la source (SI) en cherchant le zéro final: incrémente SI et lit la valeur pointée par SI. La condition d'arrêt est la rencontre avec l'octet à 0.

    2) SI doit alors pointer sur le 0 ou l'octet d'après, suivant comment tu procède.
    - Si tu (le registre SI) pointes sur le 0: décrémente SI de 1. SI pointe alors sur la dernière lettre de la chaine.
    - Si tu (le registre SI) pointes après le 0: soustrait 2 à SI. SI pointe alors sur la dernière lettre de la chaine.

    3) Comme SI pointe sur la dernière lettre de la chaîne:

    - 3-a) Prend le caractère pointé par SI.
    - 3-b) Met le dans le buffer pointé par DI.
    - 3-c) décrémente SI. Si SI pointe vers une adresse inférieure à ta sauvegarde de SI (cf. point 0), stop la boucle.
    - 3-d) Incrémente DI.
    - 3-e) Retour à 3-a)

    4) Restaure SI et DI.

    5) Retour à l'appelant.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2010
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Je vous remercie pour toutes ces informations. Maintenant j'y vois plus claire et ma procédure fonctionne.

    @Obsidian: Merci pour l'astuce, j'y avait pas pensé, cependant je devais créer une procédure qui prend en argument l'adresse du mot à inverser, puis l'adresse du mot où sera stocker le mot inversé. J'ai donc utilisé la solution de Neitsa qui m'a débloqué.

    @Neitsa: Merci pour le coup de pouce. J'avais tenté de faire ça avant mais je m'y était mal pris en fait.

    Bon dimanche

Discussions similaires

  1. afficher un tableau 2 dimensions dans une fenetre
    Par igor24 dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 29/04/2006, 14h50
  2. Réponses: 6
    Dernier message: 16/02/2006, 15h40
  3. Réponses: 2
    Dernier message: 17/01/2006, 14h18
  4. [JpGraph] Passage d'un tableau en paramètre dans une URL pour JPgraph
    Par crazydiver_e2 dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 16/01/2006, 17h15
  5. Passer un tableau en parametre dans une fonction js
    Par hellmaster78 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 19/06/2005, 15h35

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