Messagepar Phœnix44@44 » sam. 19 oct. 2024 21:17
[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