Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1296 connectés 

  FORUM HardWare.fr
  Programmation
  ASM

  Problème sur un devoir en assembleur [Help : c'est pas simple <:'o( ]

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème sur un devoir en assembleur [Help : c'est pas simple <:'o( ]

n°269730
yannick_fr​ere
Posté le 14-12-2002 à 18:19:30  profilanswer
 

Je dois faire un programme en assembleur qui teste si une chaine de caractères (qu'on entre au clavier) est un palindrome ou non (--> même chose qu'on la lise de gauche à droite ou de droite à gauche).
 
J'ai écrit le programme, mais il m'indique toujours que ce que j'ai entré n'est pas un palindrome (même les palindromes, d'où le problème ;o) et je ne vois pas du tout où se trouve l'erreur ! La logique du programme me semble bonne pourtant ! Le traducteur ne me signale aucune erreur (juste un warning, mais inévitable).
 

.model small
.stack
.data
    ac_intro DB "Veuillez entrer la chaine de caractères à tester : $"
    ac_pos DB 0ah, 0dh, "La chaine que vous avez entré est un palindrome !$"
    ac_neg DB 0ah, 0dh, "La chaine que vous avez entré n'est pas un palindrome !$"
    ac_work DB 250, ?, 251 dup ('$')
 
.code
 
main :
    mov ax, @data
    mov ds, ax
     
    mov ax, 0900h
    lea dx, ac_intro
    int 21h ;affichage du message d'intro
 
    mov ax, 0a00h
    lea dx, ac_work
    int 21h ;saisie de la string
 
    mov si, 2
    mov di, ac_work[1]
    inc di ;initialisation des variables d'indice : si pour le premier élément de la chaine à tester et di pour le dernier
 
 
until :
    cmp si, di
    jae fin1
    cmp ac_work[si], 20h
    je si_space
    cmp ac_work[di], 20h
    je di_space
    mov dl, ac_work[di]
    cmp ac_work[si], dl
    jne fin2
    dec di
    inc si
    jmp until
 
si_space :
    inc si
    jmp until
 
di_space :
    dec di
    jmp until
 
fin1 :
    mov ax, 0900h ; affichage du message de succès
    lea dx, ac_pos
    int 21h
    jmp quit
 
fin2 :
    mov ax, 0900h ; affichage du message d'échec
    lea dx, ac_neg
    int 21h
     
quit :
    mov ax, 4c00h
    int 21h
 
end main


 
 
Explication sur la partie "until" : tant que si <= que di, je regarde si l'élément repéré par si est un espace blanc (j'aurais pu mettre ' ';). Si c'est le cas, je passe à l'élément suivant (inc si). Idem pour di (avec dec di le cas échéant).
Si les éléments repérés par si et di sont tous les deux des caractères, alors je regarde s'ils sont les mêmes. Si oui, je continue, si non je coupe !
 
 
Voila, je ne vois pas où se trouve l'erreur :o/ Quelqu'un pourrait-il m'aider ? C'est sûrement une bétise, mais bon !
Merci d'avance !


Message édité par yannick_frere le 15-12-2002 à 14:06:58
mood
Publicité
Posté le 14-12-2002 à 18:19:30  profilanswer
 

n°269768
yannick_fr​ere
Posté le 14-12-2002 à 19:51:34  profilanswer
 

S'il vous plait, il n'y a personne pour me donner un petit coup de main ?  :(

n°269792
bjone
Insert booze to continue
Posté le 14-12-2002 à 21:16:38  profilanswer
 

bin pour ton histoire d'espace, tu doit "sauter" tout les espaces du début, et sauter tout les espaces de fin, et ensuite faire la comparaison "croisée", moi je vois l'algo comme ça:
 
deb: chaine saisie
fin: pointeur
 
 
;positionnement à la fin
 
fin<-deb
 
tant que fin != 0
     avancer fin
 
; on bouffe les espaces du début
 
tant que deb == espace
     avancer deb
 
; on bouffe les espaces de fin
 
   reculer fin
tant que fin == espace
 
; comparaison croisée
 
tant que deb==fin et adresse deb < adresse fin
   avancer deb
   reculer fin
 
si deb==fin
   c'est un palindrome
 
 
 
ça doit être ça l'algo à coder non ?

n°269797
yannick_fr​ere
Posté le 14-12-2002 à 21:33:40  profilanswer
 

Merci pour ton aide, Bjone !
 
Ce que tu m'as proposé ne suffira pas  :(
Parce que tu élimines les espaces du début et de la fin, mais il pourrait y en avoir au milieu !
Du style "  abba ab ba abba    " : il y a des espaces au début et à la fin, mais aussi au milieu de la chaine ! Et je ne dois pas en tenir compte !
 
Dans mon programme, je compare les éléments du début et de la fin tant que ce ne sont pas des espaces ... Donc, de cette manière, je ne tiens compte ni des espaces des extrémités, ni de ceux dans la chaine.
Of course, il y a d'autres manières de faire (style ne recopier que les caractères différents de ' ' dans un autre tableau et tester si les caractères forment un palindrome). Le problème, c'est que j'aimerais comprendre mon erreur dans ce programme-ci ! Je ne la trouve pas !
 
Mais merci pour ton aide ! Si toi ou d'autres avez encore des suggestions, n'hésitez pas ! :)

n°269876
bjone
Insert booze to continue
Posté le 15-12-2002 à 01:34:47  profilanswer
 

"  abba ab ba abba    " passera pas...
mais   "abba ab ba abba" passera...
 
rien à foutre des espaces à -l'intérieur-, l'espace est un caractère comme un autre, seul les espaces de trop au début et à la fin feront chier, mais ceux entre, je vois pas le problème...
 
comment vois-tu ta routine ?
doit-elle considérer que toute la chaine saisie doit passer au teste du palindrome ?
 
du style: "azertytreza"
 
ou tu dois essayer des séparer les mots pour les tester séparément ?
 
du style:         le bo kayak de bob"
palindromes trouvés:      ^       ^
 
si c'est le premier cas je vois pas pourquoi tu te préoccupes des espaces, sauf si ton prof t'as indiqué que tu devais "sauter" les espaces, donc qu'un "oh mon bo truc" soit testé comme "ohmonbotruc"....
 
dans ce cas l'algo est effectivement:
 
 
;positionnement à la fin  
 
fin<-deb  
 
tant que fin != 0  
    avancer fin  
 
si fin==deb
   chaine vide on quitte
 
reculer fin ; positionnement sur le dernier carc non nul
 
etiquette_boucle:
 
   tant que deb == espace  
     avancer deb  
 
   tant que fin == espace  
     reculer fin  
 
si deb==fin et adresse deb < adresse fin  
  avancer deb  
  reculer fin  
  boucler à etiquette
 
si deb==fin  
  c'est un palindrome  
 

n°269988
yannick_fr​ere
Posté le 15-12-2002 à 14:02:15  profilanswer
 

Ben encore heureux que tu es là  :jap:  
 
 
Alors : je dois faire le test "palindrome" sur toute la chaine et pas sur chaque mot séparément. Cependant, dans la chaine, je dois sauter les espaces ! De sorte que "aze r ty y tre za" soit bien un palindrome alors que ce n'est pas vraiment symétrique à première vue ("géométriquement" parlant ...).
 
Donc, je crois que l'algo que tu as proposé à la fin correspond bien à ce que je cherche à faire ! Et je pense que c'est grosso modo ce que mon programme fait ! Je vais essayer de le réexpliquer ! Parce que tu vois, je préfèrerais comprendre pourquoi le mien ne fonctionne pas ! Je pourrais naturellement faire d'autres versions, mais ça m'ennuie de ne pas comprendre pourquoi celui-ci ne va pas !
 
Donc, je reprend en détail ! J'espère que tu pourras trouver ce qui coince parce que je cale sérieusement !
 
.model small  
.stack  
.data  
   ac_intro DB "Veuillez entrer la chaine de caractères à tester : $"  
   ac_pos DB 0ah, 0dh, "La chaine que vous avez entré est un palindrome !$"  
   ac_neg DB 0ah, 0dh, "La chaine que vous avez entré n'est pas un palindrome !$"  
   ac_work DB 250, ?, 251 dup ('$';)
 
.code  
 
main :  
   mov ax, @data  
   mov ds, ax  
     
   mov ax, 0900h  
   lea dx, ac_intro  
   int 21h ;affichage du message d'intro  
 
   mov ax, 0a00h  
   lea dx, ac_work  
   int 21h

;Cette sous fonction du DOS permet de saisir une chaine avec un certain nombre de caractère maximum. Ce nombre est placé dans le premier octet du tableau ac_work (ici : 250). Elle place les caractères encodés dans le 3° octet et les suivants (j'ai prévu 251 emplacements). Elle renvoie en plus le nombre de caractère qui a été effectivement encodé par l'utilisateur et place ce nombre dans le second octet de ac_work (à la place du '?').


   mov si, 2  
   mov di, ac_work[1]  
   inc di  

;Le registre SI correspond à ton "adresse deb" (plus ou moins, car c'est en fait l'offset par rapport à l'adresse de ac_work) et DI à "adresse fin". Je place si sur le premier caractère de la chaine encodée (qui se trouve au 3° octet du tableau ac_work)(si je voulais pointer le 1° caractère, je mettrais si à 0, pour le 2°, si=1 et pour le 3°, si=2).
Pour di, je récupère le nombre de caractère encodés par l'utilisateur stocké dans le 2° octet du tableau ac_work (à la place du '?') et puisque le début de la chaine est en 2 et non en 0, j'ajoute 1 à di. D'après les tests que j'ai pu faire, si et di sont correctement initialisés.


 
until :  
   cmp si, di  
   jae fin1  
   cmp ac_work[si], 20h  
   je si_space  
   cmp ac_work[di], 20h  
   je di_space  
   mov dl, ac_work[di]  
   cmp ac_work[si], dl  
   jne fin2  
   dec di  
   inc si  
   jmp until  
 
si_space :  
   inc si  
   jmp until  
 
di_space :  
   dec di  
   jmp until
 

;Pour toute la boucle, voici ce que je fais :
boucle:
if (si >= di) {c'est un palindrome ;}
if (ac_work[si]==' ') {si = si + 1; retour à l'étiquette "boucle"}
if (ac_work[di]==' ') {di = di - 1; retour à l'étiquette "boucle"} /*De cette manière, j'ignore bien TOUS les espaces, où qu'ils soient*/
if (ac_work[si] == ac_work[di]) {si = si + 1; di = di - 1; retour à l'étiquette "boucle"}
else {ce n'est pas un palindrome}


 
 
fin1 :  
   mov ax, 0900h ; affichage du message de succès  
   lea dx, ac_pos  
   int 21h  
   jmp quit  
 
fin2 :  
   mov ax, 0900h ; affichage du message d'échec  
   lea dx, ac_neg  
   int 21h  
     
quit :  
   mov ax, 4c00h  
   int 21h  
 
end main
 
 
Voila ! Donc, je sais bien que je peux faire d'autres versions de ce programme, et c'est ce que je ferai si personne ne trouve mon erreur ! Mais j'aimerais vraiment bien comprendre pourquoi ceci ne fonctionne pas !
Merci pour ton aide (et celle des autres, s'il y en a un jour  :)  
 
:hello:

n°270072
bjone
Insert booze to continue
Posté le 15-12-2002 à 19:43:38  profilanswer
 

je penses que tu pourrais réorganiser tes boucles pour plus de clarté....

n°272111
Biglo
Posté le 18-12-2002 à 13:10:48  profilanswer
 

Salut,
 
D'après les quelques tests que j'ai réalisés, je dirai que DI n'est pas bien initialisé comme tu le penses.
 
C'est un registre 16 bits et tu places dedans le nombre de caractères lus, qui tient sur 1 octet.  
 
Ceci devrait arranger le problème:
 

Code :
  1. mov bx,offset ac_work
  2. mov al,[bx+1]
  3. mov ah,0
  4. mov di,ax
  5. inc di


 
Ce n'est peut-être pas très optimisé mais le prog que j'ai fait ainsi fonctionne.
 
J'espère t'avoir aidé.
 
@+

n°281626
yannick_fr​ere
Posté le 08-01-2003 à 00:00:14  profilanswer
 

Biglo a écrit :

Salut,
 
D'après les quelques tests que j'ai réalisés, je dirai que DI n'est pas bien initialisé comme tu le penses.
 
C'est un registre 16 bits et tu places dedans le nombre de caractères lus, qui tient sur 1 octet.  
 
Ceci devrait arranger le problème:
 

Code :
  1. mov bx,offset ac_work
  2. mov al,[bx+1]
  3. mov ah,0
  4. mov di,ax
  5. inc di


 
Ce n'est peut-être pas très optimisé mais le prog que j'ai fait ainsi fonctionne.
 
J'espère t'avoir aidé.
 
@+


 
 
Oups, je suis un peu en retard ^^
Mais effectivement, tu avais raison : c'était bien le problème que tu as souligné, le reste fonctionnait bien ^^
En fait, j'avais trouvé tout seul il y a quelques semaines ! J'aurais peut-être dû posté la réponse pour t'éviter de chercher inutilement  :( Je ne l'ai pas fait parce que mon problème n'avait pas eu un grand succès  :)
 
Donc, je répond surtout pour te dire merci d'avoir répondu à mon message et d'avoir essayé de m'aider :jap:


Message édité par yannick_frere le 08-01-2003 à 00:01:21

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  ASM

  Problème sur un devoir en assembleur [Help : c'est pas simple <:'o( ]

 

Sujets relatifs
question bete : probleme dans la déclaration d'un tableauhelp liens,frames,cadres,cells,tabl es
[ACCESS] Problème de requetteRequête SQL sur controle ADO - Problème
[JAVA] Problème avec javax.servlet :/[ASP] HELP ! sur FILTER()
[JS] Petit probleme de retour à la window par défaut apres un popupdernier probleme a resoudre.
gors problème de récupération de données, URGENT[Java] probleme setSize + repaint
Plus de sujets relatifs à : Problème sur un devoir en assembleur [Help : c'est pas simple <:'o( ]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR