- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Modérateur : mazertoc
Je suppose que les nombres 16 bits sont rangés par poids décroissant (haut poids puis bas poids)
Mais alors dans le sous- programme paire ne devrait-on pas lire
Code : Tout sélectionner
bcf STATUS,C
rlf multiplicande+0,F
rlf multiplicande+1,F
rlf multiplicande+2,F
rlf multiplicande+3,F
plutôt que
Code : Tout sélectionner
bcf STATUS,C
rlf multiplicande,F
rlf multiplicande,F
rlf multiplicande,F
rlf multiplicande,F
chose analogue dans le sous-programme impaire
et bien vu pour m'avoir averti de mon erreur tu as raison, j'ai oublié de le rajouter lors de la modification du code.
Pourtant dans mon code ils sont bien présent je sais pas ce qui c'est passé.
il faudrait le corriger pour ne pas induire les débutants à des erreurs, si Jérémy pouvait me permettre de le faire ça serait bien
Je vais remettre un corrective dans la soirée, sur ta suite
pour ta vigilance, et ton intervention.
A++
Jérémy
Code : Tout sélectionner
;***********************************************************************************************
;*************** Multiplication 16 bits sur 16 bis, avec résultat sur 32 bits ******************
;***********************************************************************************************
Errorlevel-302 ; Supprime le message "Ensure that bank bits are correct"
list p=16F628A ; processeur utilisé
#include <p16F628A.inc> ; Définitions des constantes
;******************************* configuration sans quartz *************************************
__CONFIG _CP_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _BOREN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
;**********************************************************************************************
;****************************** déclaration des variables *************************************
;**********************************************************************************************
CBLOCK H'2C'
multiplicateur :2
multiplicande :4
produit :4
loop1 :1
ENDC
;***************************** adresse de depart après reset **********************************
ORG H'00'
goto debut
ORG H'04'
retfie
;**********************************************************************************************
debut
;**********************************************************************************************
BANKSEL PCON ; on passe en bank 1
;***************** configuration sans quartz avec le registre PCON en bank 1 *******************
; OSCF
; V
movlw B'00001000' ; PCON B'00001000' mettre l'oscillateur sur la fréquence de 4MHz
movwf PCON ; PCON B'00000000' fréquence de 48KHz
;************************ configuration du registre OPTION_REG en bank 1 ***********************
movlw B'10000000' ; résistanse hors service
movwf OPTION_REG ;
;********************* configuration des registres TRISA & TRISB en bank 1 *********************
movlw B'00100000' ; B'00100000'
movwf TRISA ; 17(RA0),18(RA1),1(RA2),2(RA3),3(RA4),4(RA5),15(RA6),16(RA7)
movlw B'00000000' ; B'00000000'
movwf TRISB ; 6(RB0),7(RB1),8(RB2),9(RB3),10(RB4),11(RB5),12(RB6),13(RB7)
;**********************************************************************************************
BANKSEL CMCON ; on passe en bank 0
;************************ configuration du registre CMCON en bank 0 **************************
movlw B'00000111' ; le mode 111 pour utiliser RA0 RA1 RA2 RA3 en E/S
movwf CMCON ; inactivation des comparateurs analogiques
;********************* configuration du registre INTCON en bank 0,1,2,3 ***********************
movlw B'00000000' ; interruption général hors service
movwf INTCON ;
;******************************* début du programme principal ********************************
clrf PORTA ; mise à zéro du PORTA
clrf PORTB ; mise à zéro du PORTB
;********************** mettre à zéro les variables qu'on va utiliser **************************
movlw D'10' ; nombre de variable utilisé pour la multiplication
movwf loop1
movlw H'2C' ; adresse de départ de la première variable
movwf FSR
call efface_variable
;-----------------------------------------------------------------------------------------------
movlw D'255' ; nombre à titre d'exemple 65535
movwf multiplicande+0
movlw D'255'
movwf multiplicande+1
movlw D'21' ; nombre à titre d'exemple 2837
movwf multiplicateur+0 ;
movlw D'11'
movwf multiplicateur+1
;-----------------------------------------------------------------------------------------------
call multiplie ; 65535
; x 2837
terminer ; _______
nop ; 185922795 <-- résultat sur 32 bits, se trouve dans produit
goto terminer
;-----------------------------------------------------------------------------------------------
multiplie
btfsc multiplicateur+0,0
call impaire
paire
movf multiplicateur+0,W
xorlw D'1'
btfsc STATUS,Z
return
bcf STATUS,C
rlf multiplicande+0,F
rlf multiplicande+1,F
rlf multiplicande+2,F
rlf multiplicande+3,F
bcf STATUS,C
rrf multiplicateur+1,F
rrf multiplicateur+0,F
btfss multiplicateur,0
goto paire
impaire
bcf STATUS,C
movf multiplicande+0,W
addwf produit+0,F
btfsc STATUS,C
call v1
movf multiplicande+1,W
addwf produit+1,F
btfsc STATUS,C
call v2
movf multiplicande+2,W
addwf produit+2,F
btfsc STATUS,C
call v3
movf multiplicande+3,W
addwf produit+3,F
goto paire
;******************************************************************************************
v1
movlw B'00000001'
bcf STATUS,C
addwf produit+1,F
btfss STATUS,C
return
v2
movlw B'00000001'
bcf STATUS,C
addwf produit+2,F
btfss STATUS,C
return
v3
movlw B'00000001'
bcf STATUS,C
addwf produit+3,F
return
;-----------------------------------------------------------------------------------------------
efface_variable
clrf INDF
incf FSR,F
decfsz loop1,F
goto efface_variable
return
;-----------------------------------------------------------------------------------------------
End
Fichier joint
A++
Qui n'est jamais tombé sur ce piège des copier/coller trop rapides ?
Je suggère que tu précises qu'il est question là d'une multiplication d'entiers 16 bits non-signés, bien que ce soit assez évident avec les seuils que tu donnes. J'ai souvenir d'échanges sur le sujet signés/ non signés où certains ne semblaient pas s'y retrouver.
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
JJE a écrit :Source du message bien que ce soit assez évident avec les seuils que tu donnes
Euhhhhhh...... pas si évident que ca ! lol.
Je l'ai mis dans le raccourci en #1 . M e dire si il y a des modifications à apportées?
JJE a écrit :Source du message Je suggère que tu précises qu'il est question là d'une multiplication d'entiers 16 bits non-signés
Jérémy a écrit :Source du message M e dire si il y a des modifications à apportées?
Jérémy qui à tout compris l'a fait automatiquement, c'est parfait comme ça.
à vous deux
A++
je reviens sur ce sujet qui date, il est vrai.
Quelques petites remarques sur cet exemple de partage de code.
Bravo pour sa présentation et sa clarté.
Si je veux me servir de ce sous-programme, que dois-je faire :
1 - dans le CBlock définissant les variables de mon programme, je dois recopier
Code : Tout sélectionner
multiplicateur :2
multiplicande :4
produit :4
2 - dans mon programme lui même je dois recopier le source de sous-programme proposé
3 - Admettons que je dispose de 3 variables V1, V2, Res initialisées et que je veuille mettre dans Res le résultat de V1*V2
. il me faut
3.1 copier V1 dans multiplicateur et V2 dans multiplicande :
Code : Tout sélectionner
movf V1, W
movwf multiplicateur
movf V1+1, W
movwf multiplicateur+1
movf V2 W
movwf multiplicande
movf V2+1, W
movwf multiplicande+1
3.2 appeler la fonction
Code : Tout sélectionner
call multiplie
3.2 récupérer le résultat
Code : Tout sélectionner
movf produit, w
movwf Res
movf produit+1, w
movwf Res+1
Et cela à chaque fois que j'aurai à effectuer une multiplication 16 bits et là, on ne se préoccupe pas des problèmes de banque ni de page.
Vue la répétitivité, il me semble préférable de faire bosser l'assembleur. Une méthode que j'avais décrite ici et mise en oeuvre dans de nombreux sujets ces derniers mois serait certainement à utiliser.
4 - Telle que mis en oeuvre dans le paragraphe 3, cette méthode va à l'échec dès le deuxième appel car la mise à 0 du produit est effectuée en dehors de la procédure et je ne l'ai pas faite. Deux instructions à ajouter dans 3.1.
C'est vrai que c'est un peu de travail en plus et ce n'est pas le plus intéressant. Quand on a déniché un bon algorithme, qu'on l'a codé, qu'on l'a testé, qu'on l'a présenté proprement par respect du lecteur, on a de bonnes raisons d'être satisfait et et à Temps-X
JJE a écrit :Source du message Telle que mis en œuvre dans le paragraphe 3, cette méthode va à l'échec dès le deuxième appel car la mise à 0 du produit est effectuée en dehors de la procédure et je ne l'ai pas faite. Deux instructions à ajouter dans 3.1.
Le résultat du produit se fait sur une longueur de 32 bits, ce qui donne,
Code : Tout sélectionner
movf produit,W
movwf res8
movf produit+1,W
movwf res8+1
movf produit+2,W
movwf res8+2
movf produit+3,W
movwf res8+3
Il appartient à l'utilisateur de remettre les variables à zéro, c'est bien pour cela que j'ai fait dans l'exemple une fonction de remis à zéro
Code : Tout sélectionner
;-----------------------------------------------------------------------------------------------
movlw D'10' ; nombre de variable utilisé pour la multiplication
movwf loop1
movlw H'2C' ; peut être remplacé par movlw multiplicateur, pour des adresses rangés
movwf FSR ; adresse de départ de la première variable
call efface_variable
;-----------------------------------------------------------------------------------------------
efface_variable
clrf INDF
incf FSR,F
decfsz loop1,F
goto efface_variable
return
;-----------------------------------------------------------------------------------------------
ça évite cela
Code : Tout sélectionner
clrf multiplicateur+0
clrf multiplicateur+1
clrf multiplicande+0
clrf multiplicande+1
clrf multiplicande+2
clrf multiplicande+3
clrf produit+0
clrf produit+1
clrf produit+2
clrf produit+3
J'ai voulu présenter une méthode de remis à zéro, qui peut être utilisé pour effacement de très grande variable.
J'ai testé ma méthode et elle fonctionne très bien, je m'en sert souvent,
Dans cette méthode en retrouve une addition sur 32 bits, pour comprendre comment fonctionne cette multiplication il faut réfléchir,
avis au spécialiste des mathématiques.......
A+
Retourner vers « Langage ASM »
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 117 invités