Microprocesseur intel 8086
Fermé
yeona9
Messages postés
7
Date d'inscription
mardi 4 mars 2014
Statut
Membre
Dernière intervention
6 mars 2014
-
4 mars 2014 à 19:22
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 - 7 mars 2014 à 10:12
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 - 7 mars 2014 à 10:12
A voir également:
- Microprocesseur intel 8086
- Assistant pilotes et support intel - Télécharger - Pilotes & Matériel
- Intel hd graphics 4600 ✓ - Forum Audio
- Intel me password ✓ - Forum Carte-mère/mémoire
- Intel hd graphics 4400 - Forum Matériel & Système
- Intel pentium avis ✓ - Forum Matériel & Système
5 réponses
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
4 mars 2014 à 20:38
4 mars 2014 à 20:38
Bonjour,
Pour éviter de perdre l'adresse de retour il suffirait d'utiliser call-ret tout simplement, non? Montre donc ton programme pour voir ce qui cloche!
Pour éviter de perdre l'adresse de retour il suffirait d'utiliser call-ret tout simplement, non? Montre donc ton programme pour voir ce qui cloche!
yeona9
Messages postés
7
Date d'inscription
mardi 4 mars 2014
Statut
Membre
Dernière intervention
6 mars 2014
4 mars 2014 à 21:56
4 mars 2014 à 21:56
Voila le programme que j'ai fait :
jmp debut
val dw 0002h
F dw ?
debut:
mov cx,val
push cx
call fibo
pop F
and F,0FF00h
hlt
;_________________________________
fibo proc near
mov ax,0000h
cmp ax,0001h
jne start
cmp dl,cl
ja fin
add bh,bl
mov bl,dh
mov dh,bh
inc dl
call fibo
start: push bp
mov bp,sp
push dx
push bx
mov dx,0100h
mov bx,0000h
mov cx,[bp+4]
inc ax
fin: mov [bp+4],bx
pop bx
pop dx
pop bp
endp fibo
ret
jmp debut
val dw 0002h
F dw ?
debut:
mov cx,val
push cx
call fibo
pop F
and F,0FF00h
hlt
;_________________________________
fibo proc near
mov ax,0000h
cmp ax,0001h
jne start
cmp dl,cl
ja fin
add bh,bl
mov bl,dh
mov dh,bh
inc dl
call fibo
start: push bp
mov bp,sp
push dx
push bx
mov dx,0100h
mov bx,0000h
mov cx,[bp+4]
inc ax
fin: mov [bp+4],bx
pop bx
pop dx
pop bp
endp fibo
ret
yeona9
Messages postés
7
Date d'inscription
mardi 4 mars 2014
Statut
Membre
Dernière intervention
6 mars 2014
4 mars 2014 à 22:16
4 mars 2014 à 22:16
ET VOILA LA FONCTION PROPRE NON RÉCURSIVE AVEC LAQUELLE J AI TRAVAILLÉ NORMAL ET ELLE MARCHE TRÈS BIEN
jmp debut
val dw 0005h
F dw ?
debut:
mov cx,val
push cx
call fibo
pop F
and F,0FF00h
hlt
;_________________________________
fibo proc near
push bp
mov bp,sp
push dx
push bx
mov dx,0100h
mov bx,0000h
mov cx,[bp+4]
retour: cmp dl,cl
ja fin
add bh,bl
mov bl,dh
mov dh,bh
inc dl
jmp retour
fin: mov [bp+4],bx
pop bx
pop dx
pop bp
endp fibo
ret
jmp debut
val dw 0005h
F dw ?
debut:
mov cx,val
push cx
call fibo
pop F
and F,0FF00h
hlt
;_________________________________
fibo proc near
push bp
mov bp,sp
push dx
push bx
mov dx,0100h
mov bx,0000h
mov cx,[bp+4]
retour: cmp dl,cl
ja fin
add bh,bl
mov bl,dh
mov dh,bh
inc dl
jmp retour
fin: mov [bp+4],bx
pop bx
pop dx
pop bp
endp fibo
ret
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
Modifié par nicocorico le 4/03/2014 à 22:34
Modifié par nicocorico le 4/03/2014 à 22:34
Huum.. c'est normal que tu perdes ton cadre de pile oui, puisque tu écris à une adresse illégale! Ton [Bp+04] n'est pas initialisé dans le cadre de pile local et peut être écrasé par toute interruption. Ce qui ne convient pas c'est la manière de retourner le paramètre, il vaut mieux qu'il soit retourné dans "ax" par convention. Sinon, si tu veux retourner un paramètre par la pile, il faut que ce soit l'appelant qui alloue l'espace pour ce paramètre, et non pas la fonction elle-même...
De plus, je trouve que tu fais bien compliqué pour une suite de fibonacci! à quoi bon s'embêter avec une fonction récursive alors qu'il s'agit d'additionner les deux derniers termes pour trouver le suivant! Autrement dit tu ajoute le terme précédent à celui que tu viens de trouver, et ça donne le suivant!
Bon, je fais pas d'asm 16 bits sans structuration, mais en gros ça donnerait ça:
Le chêne aussi était un gland, avant d'être un chêne
De plus, je trouve que tu fais bien compliqué pour une suite de fibonacci! à quoi bon s'embêter avec une fonction récursive alors qu'il s'agit d'additionner les deux derniers termes pour trouver le suivant! Autrement dit tu ajoute le terme précédent à celui que tu viens de trouver, et ça donne le suivant!
Bon, je fais pas d'asm 16 bits sans structuration, mais en gros ça donnerait ça:
Result DW [0..1000]
Debut:
Mov DI,@Result
Mov [DI],0
Mov [DI+04],1
Mov CX,998
Mov AX,01
@Bcl:
Add AX,[DI]
Mov [DI+08],AX
Add DI,04
Dec CX;
Jnz @Bcl;
Le chêne aussi était un gland, avant d'être un chêne
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
4 mars 2014 à 22:35
4 mars 2014 à 22:35
Ha oui alors attend, j'avais pas vu ton post entre-temps, je regarde ce que ça donne!
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
Modifié par nicocorico le 4/03/2014 à 22:43
Modifié par nicocorico le 4/03/2014 à 22:43
Ha oui, finalement on fait un peu la même chose maintenant, mais tu peux simplifier tout ton code! En fait la récursivité ne sert à rien du tout, ça ne fait que ralentir et alourdir, ce qu'il faut c'est soit remplir directement un tableau, soit renvoyer un résultat unique après un nombre d'itérations.
Et je vois que tu t'emmêles un peu les pédales dans les registres au niveau de la routine de calcul proprement dite, il faudrait que tu remettes à plat ta boucle maintenant que tu a repensée ta fonction! Tout le corps de fonction c'est de la soupe de registres épars! Et il faut songer que huit bits c'est très limité pour une suite de fibonacci! Tu dois y arriver dès la quinzaine d'itérations!
Et je vois que tu t'emmêles un peu les pédales dans les registres au niveau de la routine de calcul proprement dite, il faudrait que tu remettes à plat ta boucle maintenant que tu a repensée ta fonction! Tout le corps de fonction c'est de la soupe de registres épars! Et il faut songer que huit bits c'est très limité pour une suite de fibonacci! Tu dois y arriver dès la quinzaine d'itérations!
yeona9
Messages postés
7
Date d'inscription
mardi 4 mars 2014
Statut
Membre
Dernière intervention
6 mars 2014
4 mars 2014 à 22:57
4 mars 2014 à 22:57
oui j'ai bien compris ça, le problème c'est que notre prof a insisté sur cette histoire de récursivité, même vraiment je sais bien qu'elle sert a rien, j'aurai du faire ce travaille plus simple que ça, mais il veut savoir comment on va manipuler la pile, alors je vais essayer ce que vous m'avez dit et je vous dis après qu'est ce que ça donne. Merci énormément pour votre aide :)
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
Modifié par nicocorico le 4/03/2014 à 23:04
Modifié par nicocorico le 4/03/2014 à 23:04
De rien, ça me fait plaisir d'aider sur l'assembleur!
J'aurais peut-être plus de temps ce soir, mais je veux bien voir ce que tu auras fais pour résoudre ton problème de pile!
Je pense que pour simplifier, il faut que tu passes les paramètres à la fonction par les registres et que tu récupères par ax en retour (c'est le standard d'appel optimisé de fonction), et les valeurs que tu veux sauver au sein de la fonction, tu les sauves sur la pile. Autrement dit, tu conserves le problème de la pile qu'au sein de la fonction, en empilant avant l'appel récursif et en dépilant après, c'est plus simple. Oublie pas de faire tes calculs sur 16 bits aussi, 8 bits c'est trop court!
Bon courage!
J'aurais peut-être plus de temps ce soir, mais je veux bien voir ce que tu auras fais pour résoudre ton problème de pile!
Je pense que pour simplifier, il faut que tu passes les paramètres à la fonction par les registres et que tu récupères par ax en retour (c'est le standard d'appel optimisé de fonction), et les valeurs que tu veux sauver au sein de la fonction, tu les sauves sur la pile. Autrement dit, tu conserves le problème de la pile qu'au sein de la fonction, en empilant avant l'appel récursif et en dépilant après, c'est plus simple. Oublie pas de faire tes calculs sur 16 bits aussi, 8 bits c'est trop court!
Bon courage!
yeona9
Messages postés
7
Date d'inscription
mardi 4 mars 2014
Statut
Membre
Dernière intervention
6 mars 2014
4 mars 2014 à 23:13
4 mars 2014 à 23:13
Merci je vais bien le faire aussi sur 16 bits, je vais vous envoyer ma solution après, je vous souhaite une bonne soiré. Merci
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
Modifié par nicocorico le 7/03/2014 à 10:20
Modifié par nicocorico le 7/03/2014 à 10:20
Oui ça va merci! Toi aussi j'espère!
Huuum!
à ce que je vois la récursivité marche par chance plus que par logique en fait! Disons qu'étant donné qu'elle ne sert vraiment à rien ça pose pas de soucis, mais sinon elle ne fonctionnerait pas! Notamment tu te cantonne à mettre les résultats aux deux emplacement définis dès le départ car tu fais "add sp,06" (au lieu de sub sp,06) et sans initialiser les valeurs par la suite! En fait tu ne fais pas du récursif, tu écrases l'appel de fonction précédent et les valeurs locales, donc ça revient au même que d'appeler une seule fonction. Mais de toute façon on ne peut pas récupérer les résultats en les mettant dans des variable locales comme c'est le cas, donc c'est très inutile c'est vrai! Attention au "mov [bp+8],dl " aussi, tu passes en huit bits alors que tu le lis aussi en 16 bits! Entre les deux vaut mieux choisir car certains processeurs stockent l'octet le plus faible en premier et d'autres en dernier, donc les octets sont inversés en mémoire! Sur motorola il faudrait faire "mov [bp+9],dl", donc mieux vaut faire "mov [bp+8],dx".
Et de mon point de vue, j'éliminerais le "push cx" et le fonctionnement aléatoire avec le registre "AL", je mettrais plutôt une comparaison directe avec "val" pour donner la limite. Et aussi il est inutile de faire "push dx", car ça ne sert à rien de sauvegarder sa valeur!
En restant sur la même base je te proposerais ceci qui revient exactement au même:
Ensuite, le fait de réserver un espace pour les variables avant d'appeler est jouable, mais idéalement il faut le faire de manière plus fiable, soit en passant des paramètres via la pile en les officialisant, soit en passant l'adresse des variables utilisées en implémentant un enregistrement pour les déclarer. Sinon le souci c'est qu'à la moindre modification dans la manière d'appeler la fonction on risque de bouleverser le fonctionnement de la fonction elle-même, alors qu'en utilisant des conventions plus souples on contourne le problème. Dans les langages de haut niveau, le passage des paramètres se fait par les registres ou par la pile, mais si l'appel de routine court doit être changé en appel long par exemple, les déplacements sont ajustés automatiquement. Et la convention utilise EAX,EDX et ECX pour passer des paramètres par registre, dans cet ordre, et EAX pour le retour de fonction.
Et si on veut garder l'étalement des valeurs sur la pile il faudrait faire comme ça:
Ici on utilise bien la récursivité mais on ne peut pas accéder librement aux valeurs calculées... il faudrait les mettre dans un tableau à part mais la récursivité devient alors complètement inutile! (et l'est déjà ici pour sûr). Je comprend pas pourquoi ton prof ne choisis pas un thème qui nécessite réellement une récursivité tant qu'à faire! C'est vrai que l'assembleur est tellement souple dans les branchements que la récursivité est moins souvent utile que dans les langages de haut-niveau, mais très pratique lorsqu'il s'agit de travailler sur des arbres à profondeur variable, partout où on ne sait pas combien d'éléments on aura à traiter et stocker temporairement.
Par ailleurs je trouverais plus élégant de passer un pointeur sur les deux variables plutôt que laisser la fonction piocher dedans. En fait la fonction ne devrait pas aller chercher au-dessus de l'adresse de retour due au call... Et le fait de stocker ces variables sur la pile est utile lorsqu'on est obligé de re-appeler la fonction tout en gardant des valeurs qui seront réutilisées après le résultat de l'appel, mais dans le cas présent on donne déjà tout à la fonction et il n'y a rien à faire en retour, et on pourrait tout passer pas les registres! Alors ce que je verrais comme solution, c'est que la pile ne serve pas à stocker les valeurs proprement dites, mais à stocker l'emplacement dans lequel elles doivent être stockées (dans un tableau global donc), dans ce cas précis il faudrait commencer par la fin et chaque fonction devrait conserver son pointeur et l'utiliser une fois que le calcul précédent serait effectué...
Voilà, je te laisse repenser le fonctionnement à ta sauce en essayant de faire du récursif véritable si tu en as vraiment besoin et on revoit ça!
Bon courage!
Le chêne aussi était un gland, avant d'être un chêne
Huuum!
à ce que je vois la récursivité marche par chance plus que par logique en fait! Disons qu'étant donné qu'elle ne sert vraiment à rien ça pose pas de soucis, mais sinon elle ne fonctionnerait pas! Notamment tu te cantonne à mettre les résultats aux deux emplacement définis dès le départ car tu fais "add sp,06" (au lieu de sub sp,06) et sans initialiser les valeurs par la suite! En fait tu ne fais pas du récursif, tu écrases l'appel de fonction précédent et les valeurs locales, donc ça revient au même que d'appeler une seule fonction. Mais de toute façon on ne peut pas récupérer les résultats en les mettant dans des variable locales comme c'est le cas, donc c'est très inutile c'est vrai! Attention au "mov [bp+8],dl " aussi, tu passes en huit bits alors que tu le lis aussi en 16 bits! Entre les deux vaut mieux choisir car certains processeurs stockent l'octet le plus faible en premier et d'autres en dernier, donc les octets sont inversés en mémoire! Sur motorola il faudrait faire "mov [bp+9],dl", donc mieux vaut faire "mov [bp+8],dx".
Et de mon point de vue, j'éliminerais le "push cx" et le fonctionnement aléatoire avec le registre "AL", je mettrais plutôt une comparaison directe avec "val" pour donner la limite. Et aussi il est inutile de faire "push dx", car ça ne sert à rien de sauvegarder sa valeur!
En restant sur la même base je te proposerais ceci qui revient exactement au même:
jmp debut
val dw 0008h
debut:
push word ptr 0000h
push word ptr 0001h
call fibo
Add sp,04
hlt
fibo proc near
mov dx,[sp+2]
Xchg dx,[sp+4]
Add dx,[sp+4]
Mov [sp+2],dx
cmp dx,val
jb fibo
ret
endp fibo
Ensuite, le fait de réserver un espace pour les variables avant d'appeler est jouable, mais idéalement il faut le faire de manière plus fiable, soit en passant des paramètres via la pile en les officialisant, soit en passant l'adresse des variables utilisées en implémentant un enregistrement pour les déclarer. Sinon le souci c'est qu'à la moindre modification dans la manière d'appeler la fonction on risque de bouleverser le fonctionnement de la fonction elle-même, alors qu'en utilisant des conventions plus souples on contourne le problème. Dans les langages de haut niveau, le passage des paramètres se fait par les registres ou par la pile, mais si l'appel de routine court doit être changé en appel long par exemple, les déplacements sont ajustés automatiquement. Et la convention utilise EAX,EDX et ECX pour passer des paramètres par registre, dans cet ordre, et EAX pour le retour de fonction.
Et si on veut garder l'étalement des valeurs sur la pile il faudrait faire comme ça:
jmp debut
val dw 0008h
debut:
push word ptr 0000h
push word ptr 0001h
call fibo
Add sp,04
hlt
fibo proc near
Sub sp,04
mov dx,[sp+6]
mov [sp+02],dx
add dx,[sp+8]
mov [sp],dx
cmp dx,val
jae Fin
Call Fibo
Fin:
ret 04
endp fibo
Ici on utilise bien la récursivité mais on ne peut pas accéder librement aux valeurs calculées... il faudrait les mettre dans un tableau à part mais la récursivité devient alors complètement inutile! (et l'est déjà ici pour sûr). Je comprend pas pourquoi ton prof ne choisis pas un thème qui nécessite réellement une récursivité tant qu'à faire! C'est vrai que l'assembleur est tellement souple dans les branchements que la récursivité est moins souvent utile que dans les langages de haut-niveau, mais très pratique lorsqu'il s'agit de travailler sur des arbres à profondeur variable, partout où on ne sait pas combien d'éléments on aura à traiter et stocker temporairement.
Par ailleurs je trouverais plus élégant de passer un pointeur sur les deux variables plutôt que laisser la fonction piocher dedans. En fait la fonction ne devrait pas aller chercher au-dessus de l'adresse de retour due au call... Et le fait de stocker ces variables sur la pile est utile lorsqu'on est obligé de re-appeler la fonction tout en gardant des valeurs qui seront réutilisées après le résultat de l'appel, mais dans le cas présent on donne déjà tout à la fonction et il n'y a rien à faire en retour, et on pourrait tout passer pas les registres! Alors ce que je verrais comme solution, c'est que la pile ne serve pas à stocker les valeurs proprement dites, mais à stocker l'emplacement dans lequel elles doivent être stockées (dans un tableau global donc), dans ce cas précis il faudrait commencer par la fin et chaque fonction devrait conserver son pointeur et l'utiliser une fois que le calcul précédent serait effectué...
Voilà, je te laisse repenser le fonctionnement à ta sauce en essayant de faire du récursif véritable si tu en as vraiment besoin et on revoit ça!
Bon courage!
Le chêne aussi était un gland, avant d'être un chêne