Bienvenue aux nouveaux arrivants sur FantasPic !
- 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 ---
- 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
Multiplication nombre a virgule flottante
-
Phœnix44@44

Membre- Messages : 3
- Enregistré en : octobre 2024
Salut les geek j'ai un petit blocus sur un petit projet qui est chaud pour m'aider
:
Écrire un programme en langage d'assemblage (PIC18F4680) en mode simulateur, réalisant une multiplication en virgule flottante sur des nombres représentés dans le format IEEE 754 en précision simple (32 bits). Soustrait le biais (127) à chacun des exposants avant de les additionner. Ajoute 127 au résultat final pour obtenir la représentation. Pour développer et déboguer le programme, utilise les nombres A=-18 et B=9.5. Les nombres A et B devront être stockés dans la mémoire des données (à partir de l’adresse 0x60). initialise ces espaces mémoire en quatre étapes à l’aide des instructions MOVLW et MOVWF. Il est à noter que la multiplication à réaliser consiste à faire une simple multiplication de deux nombres exprimés en binaire. Le résultat de la multiplication est un nombre exprimé sur 16 bits qui sera stocké dans les registres PRODH et PRODL. Une deuxième zone UDATA devra être présente dans le programme. Elle servira pour stocker différentes valeurs que les sous-routines produiront ou utiliseront. Utilise le plus souvent possible les appels de sous-routines (avec l’instruction CALL). Crée une sous-routine pour chacune des tâches suivantes :
a) Extraire le signe d’un nombre exprimé selon le standard IEEE 754
b) Extraire l’exposant d’un nombre exprimé selon le standard IEEE 754
c) Extraire la fraction d’un nombre exprimé selon le standard IEEE 754
Notes :
Le signe du résultat dépend du signe des deux nombres multipliés.
L'exposant utilise une réprésentation en biais.
Rétire le 1 sous-entendu;
Écrire un programme en langage d'assemblage (PIC18F4680) en mode simulateur, réalisant une multiplication en virgule flottante sur des nombres représentés dans le format IEEE 754 en précision simple (32 bits). Soustrait le biais (127) à chacun des exposants avant de les additionner. Ajoute 127 au résultat final pour obtenir la représentation. Pour développer et déboguer le programme, utilise les nombres A=-18 et B=9.5. Les nombres A et B devront être stockés dans la mémoire des données (à partir de l’adresse 0x60). initialise ces espaces mémoire en quatre étapes à l’aide des instructions MOVLW et MOVWF. Il est à noter que la multiplication à réaliser consiste à faire une simple multiplication de deux nombres exprimés en binaire. Le résultat de la multiplication est un nombre exprimé sur 16 bits qui sera stocké dans les registres PRODH et PRODL. Une deuxième zone UDATA devra être présente dans le programme. Elle servira pour stocker différentes valeurs que les sous-routines produiront ou utiliseront. Utilise le plus souvent possible les appels de sous-routines (avec l’instruction CALL). Crée une sous-routine pour chacune des tâches suivantes :
a) Extraire le signe d’un nombre exprimé selon le standard IEEE 754
b) Extraire l’exposant d’un nombre exprimé selon le standard IEEE 754
c) Extraire la fraction d’un nombre exprimé selon le standard IEEE 754
Notes :
Le signe du résultat dépend du signe des deux nombres multipliés.
L'exposant utilise une réprésentation en biais.
Rétire le 1 sous-entendu;
Multiplication nombre a virgule flottante
Bonjour,
Il y a du travail. D'abord il vaut mieux être à l'aise avec l'assembleur PIC18, comme c'est un vieux modèle de pic, MPASM est utilisable.
Ensuite la marche à suivre pour multiplier 2 flottants est expliquée ici, l'exemple est en 32 bits .
https://numeral-systems.com/ieee-754-multiply/
Par contre je n'ai pas compris pourquoi il est dit que le résultat doit être fourni sur 16 bits, le résultat est un flottant 32 bits, non ?
Il y a du travail. D'abord il vaut mieux être à l'aise avec l'assembleur PIC18, comme c'est un vieux modèle de pic, MPASM est utilisable.
Ensuite la marche à suivre pour multiplier 2 flottants est expliquée ici, l'exemple est en 32 bits .
https://numeral-systems.com/ieee-754-multiply/
Par contre je n'ai pas compris pourquoi il est dit que le résultat doit être fourni sur 16 bits, le résultat est un flottant 32 bits, non ?
Modifié en dernier par satinas le sam. 19 oct. 2024 15:36, modifié 1 fois.
Multiplication nombre a virgule flottante
Multiplication nombre a virgule flottante
-
Phœnix44@44

Membre- Messages : 3
- Enregistré en : octobre 2024
[code=asm][/; Configuration du microcontrôleur
LIST p=18F4680
#include <p18F4680.inc>
CONFIG OSC = ECIO
CONFIG FCMEN = OFF
CONFIG IESO = OFF
CONFIG PWRT = ON
CONFIG BOREN = OFF
CONFIG BORV = 2
CONFIG WDT = OFF
CONFIG WDTPS = 256
CONFIG MCLRE = ON
CONFIG LPT1OSC = OFF
CONFIG PBADEN = OFF
CONFIG STVREN = ON
CONFIG LVP = OFF
CONFIG XINST = OFF
CONFIG DEBUG = OFF
; Déclarations de mémoire
ORG 0x60
FLOAT_A RES 4 ; Nombre A en virgule flottante (4 octets)
FLOAT_B RES 4 ; Nombre B en virgule flottante (4 octets)
SIGN_RESULT RES 1 ; Signe du résultat
EXP_RESULT RES 1 ; Exposant du résultat
EXP_RESULT_B RES 1 ; Exposant de B (ajouté pour éviter l'erreur)
FRACTION_RESULT_A RES 3 ; Fraction de A
FRACTION_RESULT_B RES 3 ; Fraction de B
RESULT RES 4 ; Résultat final
RESULT_LOW RES 2 ; Résultat bas (16 bits)
RESULT_HIGH RES 2 ; Résultat haut (16 bits)
TEMP RES 4 ; Temp pour les calculs intermédiaires (élargi pour 32 bits de stockage)
; Programme principal
MAIN
; Initialisation des valeurs en mémoire pour A = -18 et B = 9.5
MOVLW 0xC1
MOVWF FLOAT_A
MOVLW 0x90
MOVWF FLOAT_A+1
MOVLW 0x00
MOVWF FLOAT_A+2
MOVLW 0x00
MOVWF FLOAT_A+3
MOVLW 0x41
MOVWF FLOAT_B
MOVLW 0x20
MOVWF FLOAT_B+1
MOVLW 0x00
MOVWF FLOAT_B+2
MOVLW 0x00
MOVWF FLOAT_B+3
; Appeler les sous-routines
CALL EXTRACT_SIGN
CALL EXTRACT_EXPONENT
CALL EXTRACT_FRACTION_A
CALL EXTRACT_FRACTION_B
CALL ADD_EXPONENTS
CALL MULTIPLY_FLOATS
CALL STORE_RESULT
GOTO MAIN
; Sous-routines
; Sous-routine : Extraction du signe de A
EXTRACT_SIGN
MOVF FLOAT_A, W
ANDLW 0x80
MOVWF SIGN_RESULT
RETURN
; Sous-routine : Extraction de l'exposant
EXTRACT_EXPONENT
MOVF FLOAT_A+1, W
ANDLW 0x7F
MOVWF EXP_RESULT
MOVLW 127
SUBWF EXP_RESULT, F
; Extraction de l'exposant de B
MOVF FLOAT_B+1, W
ANDLW 0x7F
MOVWF EXP_RESULT_B
MOVLW 127
SUBWF EXP_RESULT_B, F
RETURN
; Sous-routine : Extraction de la fraction de A
EXTRACT_FRACTION_A
MOVF FLOAT_A+1, W
ANDLW 0x7F
MOVWF FRACTION_RESULT_A
MOVF FLOAT_A+2, W
MOVWF FRACTION_RESULT_A+1
MOVF FLOAT_A+3, W
MOVWF FRACTION_RESULT_A+2
RETURN
; Sous-routine : Extraction de la fraction de B
EXTRACT_FRACTION_B
MOVF FLOAT_B+1, W
ANDLW 0x7F
MOVWF FRACTION_RESULT_B
MOVF FLOAT_B+2, W
MOVWF FRACTION_RESULT_B+1
MOVF FLOAT_B+3, W
MOVWF FRACTION_RESULT_B+2
RETURN
; Sous-routine : Addition des exposants
ADD_EXPONENTS
MOVF EXP_RESULT, W
ADDWF EXP_RESULT_B, F ; Additionner les exposants A et B
MOVLW 127
ADDWF EXP_RESULT, F ; Ajuster avec le biais
RETURN
; Sous-routine : Multiplication des fractions
MULTIPLY_FLOATS
; Charger la fraction de A dans RESULT_LOW (16 bits)
MOVF FRACTION_RESULT_A, W
MOVWF RESULT_LOW
MOVF FRACTION_RESULT_A+1, W
MOVWF RESULT_LOW+1
; Charger la fraction de B dans RESULT_HIGH (16 bits)
MOVF FRACTION_RESULT_B, W
MOVWF RESULT_HIGH
MOVF FRACTION_RESULT_B+1, W
MOVWF RESULT_HIGH+1
; Multiplier les fractions
; Utilisation d'une multiplication 32 bits x 32 bits
; pour obtenir un résultat de 64 bits
MOVF RESULT_LOW, W
MULWF RESULT_HIGH
MOVWF TEMP
MOVF RESULT_LOW+1, W
MULWF RESULT_HIGH
ADDWF TEMP+1, F
MOVF RESULT_LOW, W
MULWF RESULT_HIGH+1
ADDWF TEMP+2, F
MOVF RESULT_LOW+1, W
MULWF RESULT_HIGH+1
ADDWF TEMP+3, F
; Ajuster l'exposant du résultat
MOVF EXP_RESULT, W
ADDWF TEMP+3, F
; Stocker le résultat
MOVF TEMP, W
MOVWF RESULT
MOVF TEMP+1, W
MOVWF RESULT+1
MOVF TEMP+2, W
MOVWF RESULT+2
MOVF TEMP+3, W
MOVWF RESULT+3
RETURN
; Sous-routine : Stockage du résultat
STORE_RESULT
; Ici, le résultat est déjà dans RESULT après multiplication
; Ajuster l'exposant du résultat
MOVF EXP_RESULT, W
ADDWF RESULT+1, F
; Stocker le signe du résultat
MOVF SIGN_RESULT, W
MOVWF RESULT+3
RETURN
END
]
J'en suis là d'abord
LIST p=18F4680
#include <p18F4680.inc>
CONFIG OSC = ECIO
CONFIG FCMEN = OFF
CONFIG IESO = OFF
CONFIG PWRT = ON
CONFIG BOREN = OFF
CONFIG BORV = 2
CONFIG WDT = OFF
CONFIG WDTPS = 256
CONFIG MCLRE = ON
CONFIG LPT1OSC = OFF
CONFIG PBADEN = OFF
CONFIG STVREN = ON
CONFIG LVP = OFF
CONFIG XINST = OFF
CONFIG DEBUG = OFF
; Déclarations de mémoire
ORG 0x60
FLOAT_A RES 4 ; Nombre A en virgule flottante (4 octets)
FLOAT_B RES 4 ; Nombre B en virgule flottante (4 octets)
SIGN_RESULT RES 1 ; Signe du résultat
EXP_RESULT RES 1 ; Exposant du résultat
EXP_RESULT_B RES 1 ; Exposant de B (ajouté pour éviter l'erreur)
FRACTION_RESULT_A RES 3 ; Fraction de A
FRACTION_RESULT_B RES 3 ; Fraction de B
RESULT RES 4 ; Résultat final
RESULT_LOW RES 2 ; Résultat bas (16 bits)
RESULT_HIGH RES 2 ; Résultat haut (16 bits)
TEMP RES 4 ; Temp pour les calculs intermédiaires (élargi pour 32 bits de stockage)
; Programme principal
MAIN
; Initialisation des valeurs en mémoire pour A = -18 et B = 9.5
MOVLW 0xC1
MOVWF FLOAT_A
MOVLW 0x90
MOVWF FLOAT_A+1
MOVLW 0x00
MOVWF FLOAT_A+2
MOVLW 0x00
MOVWF FLOAT_A+3
MOVLW 0x41
MOVWF FLOAT_B
MOVLW 0x20
MOVWF FLOAT_B+1
MOVLW 0x00
MOVWF FLOAT_B+2
MOVLW 0x00
MOVWF FLOAT_B+3
; Appeler les sous-routines
CALL EXTRACT_SIGN
CALL EXTRACT_EXPONENT
CALL EXTRACT_FRACTION_A
CALL EXTRACT_FRACTION_B
CALL ADD_EXPONENTS
CALL MULTIPLY_FLOATS
CALL STORE_RESULT
GOTO MAIN
; Sous-routines
; Sous-routine : Extraction du signe de A
EXTRACT_SIGN
MOVF FLOAT_A, W
ANDLW 0x80
MOVWF SIGN_RESULT
RETURN
; Sous-routine : Extraction de l'exposant
EXTRACT_EXPONENT
MOVF FLOAT_A+1, W
ANDLW 0x7F
MOVWF EXP_RESULT
MOVLW 127
SUBWF EXP_RESULT, F
; Extraction de l'exposant de B
MOVF FLOAT_B+1, W
ANDLW 0x7F
MOVWF EXP_RESULT_B
MOVLW 127
SUBWF EXP_RESULT_B, F
RETURN
; Sous-routine : Extraction de la fraction de A
EXTRACT_FRACTION_A
MOVF FLOAT_A+1, W
ANDLW 0x7F
MOVWF FRACTION_RESULT_A
MOVF FLOAT_A+2, W
MOVWF FRACTION_RESULT_A+1
MOVF FLOAT_A+3, W
MOVWF FRACTION_RESULT_A+2
RETURN
; Sous-routine : Extraction de la fraction de B
EXTRACT_FRACTION_B
MOVF FLOAT_B+1, W
ANDLW 0x7F
MOVWF FRACTION_RESULT_B
MOVF FLOAT_B+2, W
MOVWF FRACTION_RESULT_B+1
MOVF FLOAT_B+3, W
MOVWF FRACTION_RESULT_B+2
RETURN
; Sous-routine : Addition des exposants
ADD_EXPONENTS
MOVF EXP_RESULT, W
ADDWF EXP_RESULT_B, F ; Additionner les exposants A et B
MOVLW 127
ADDWF EXP_RESULT, F ; Ajuster avec le biais
RETURN
; Sous-routine : Multiplication des fractions
MULTIPLY_FLOATS
; Charger la fraction de A dans RESULT_LOW (16 bits)
MOVF FRACTION_RESULT_A, W
MOVWF RESULT_LOW
MOVF FRACTION_RESULT_A+1, W
MOVWF RESULT_LOW+1
; Charger la fraction de B dans RESULT_HIGH (16 bits)
MOVF FRACTION_RESULT_B, W
MOVWF RESULT_HIGH
MOVF FRACTION_RESULT_B+1, W
MOVWF RESULT_HIGH+1
; Multiplier les fractions
; Utilisation d'une multiplication 32 bits x 32 bits
; pour obtenir un résultat de 64 bits
MOVF RESULT_LOW, W
MULWF RESULT_HIGH
MOVWF TEMP
MOVF RESULT_LOW+1, W
MULWF RESULT_HIGH
ADDWF TEMP+1, F
MOVF RESULT_LOW, W
MULWF RESULT_HIGH+1
ADDWF TEMP+2, F
MOVF RESULT_LOW+1, W
MULWF RESULT_HIGH+1
ADDWF TEMP+3, F
; Ajuster l'exposant du résultat
MOVF EXP_RESULT, W
ADDWF TEMP+3, F
; Stocker le résultat
MOVF TEMP, W
MOVWF RESULT
MOVF TEMP+1, W
MOVWF RESULT+1
MOVF TEMP+2, W
MOVWF RESULT+2
MOVF TEMP+3, W
MOVWF RESULT+3
RETURN
; Sous-routine : Stockage du résultat
STORE_RESULT
; Ici, le résultat est déjà dans RESULT après multiplication
; Ajuster l'exposant du résultat
MOVF EXP_RESULT, W
ADDWF RESULT+1, F
; Stocker le signe du résultat
MOVF SIGN_RESULT, W
MOVWF RESULT+3
RETURN
END
]
J'en suis là d'abord
Multiplication nombre a virgule flottante
Bonjour,
Ça sens le devoirs d'école..... c'est pour quoi faire
Pour une multiplication avec une virgule, il suffit de supprimer la virgule et de l'effectuer comme une multiplication normal, après tu rajoutes la virgule.
Beaucoup de jeune ne savent plus faire une multiplication avec une virgule....
A+
Ça sens le devoirs d'école..... c'est pour quoi faire
Pour une multiplication avec une virgule, il suffit de supprimer la virgule et de l'effectuer comme une multiplication normal, après tu rajoutes la virgule.
Beaucoup de jeune ne savent plus faire une multiplication avec une virgule....
Multiplication nombre a virgule flottante
Multiplication nombre a virgule flottante
Bonjour,
Pour que ça compile en mode relocatable, car tu utilises la directive res :
- j'ai mis la ligne "udata 0x60" devant les variables, au lieu de org
- j'ai mis la ligne "org 0x00" devant le code.
- pour stocker 9.5 je trouve 0x41180000 au lieu de 0x41200000
- tu n'as pas l'air de calculer le signe du résultat ou alors je n'ai pas compris.
- l'exposant est à cheval sur 2 octets, pourquoi tu n'en lis qu'un pour le calculer ?
- d'après ce que je comprends de la doc, il faudrait faire une multiplication 24*24 bits, il y a peut être moyen de simplifier. On ajoute avant cela le 1 implicite (24 ème bit à gauche). Ensuite on normalise en modifiant l'exposant final selon la position du premier 1 à gauche dans le résultat, prendre en compte le débordement éventuel de l'exposant. On enlève ce 1 implicite à gauche et on arrondit la mantisse finale.
Pour que ça compile en mode relocatable, car tu utilises la directive res :
- j'ai mis la ligne "udata 0x60" devant les variables, au lieu de org
- j'ai mis la ligne "org 0x00" devant le code.
- pour stocker 9.5 je trouve 0x41180000 au lieu de 0x41200000
- tu n'as pas l'air de calculer le signe du résultat ou alors je n'ai pas compris.
- l'exposant est à cheval sur 2 octets, pourquoi tu n'en lis qu'un pour le calculer ?
Code : Tout sélectionner
rlcf FLOAT_A+1,W
rlcf FLOAT_A,W
movwf EXP_RESULT
movlw 127
subwf EXP_RESULT, F - d'après ce que je comprends de la doc, il faudrait faire une multiplication 24*24 bits, il y a peut être moyen de simplifier. On ajoute avant cela le 1 implicite (24 ème bit à gauche). Ensuite on normalise en modifiant l'exposant final selon la position du premier 1 à gauche dans le résultat, prendre en compte le débordement éventuel de l'exposant. On enlève ce 1 implicite à gauche et on arrondit la mantisse finale.
Multiplication nombre a virgule flottante
-
Phœnix44@44

Membre- Messages : 3
- Enregistré en : octobre 2024
Retourner vers « Langage ASM »
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 4 invités


…grâce à ces ajustements le programme fonctionne correctement et j’ai les bonnes valeurs…!