Problème sur un devoir en assembleur [Help : c'est pas simple <:'o( ] - ASM - Programmation
Marsh Posté le 14-12-2002 à 19:51:34
S'il vous plait, il n'y a personne pour me donner un petit coup de main ?
Marsh Posté le 14-12-2002 à 21:16:38
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 ?
Marsh Posté le 14-12-2002 à 21:33:40
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 !
Marsh Posté le 15-12-2002 à 01:34:47
" 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
Marsh Posté le 15-12-2002 à 14:02:15
Ben encore heureux que tu es là
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). |
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 : |
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
Marsh Posté le 15-12-2002 à 19:43:38
je penses que tu pourrais réorganiser tes boucles pour plus de clarté....
Marsh Posté le 18-12-2002 à 13:10:48
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 :
|
Ce n'est peut-être pas très optimisé mais le prog que j'ai fait ainsi fonctionne.
J'espère t'avoir aidé.
@+
Marsh Posté le 08-01-2003 à 00:00:14
Biglo a écrit : Salut,
|
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
Marsh Posté le 14-12-2002 à 18:19:30
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 / 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