Multiplication/divisions sur 64bits pour registre 32bits

Contenu du snippet

Voici deux petites fonctions permettant d'effectuer rapidement des multiplications et des divisions sur des registres 32 bits ....

J'ai développé ce code pour un Microcontroleur type H8 (Hitachi)

A noter que si vous utiliser un processeur avec des registre 64Bits, vous pourrez faire des multis sur 64Bits.... à l'inverse, si vous n'avez qu'un µC 8Bits, rien ne vous empeche d'etendre a chose sur 16 bits (juste la variable d'occurence à changer)

A noter :

_L_reg32_1 & _H_reg32_1
_L_reg32_2 & _H_reg32_2

sont des variables 32 bits L(Low) H(High)
// la c'est pour les nouveaux, pour les pros c'etait evident ...

Source / Exemple :


;****************************************************;
;* Multiplication avec expansion en 64 bits         *;
;*                                                  *;
;* Entrées : er2 :: nombre 1 (32 bits)              *;
;*           er3 :: nombre 2 (32 bits)              *;
;*                                                  *;
;* Sorties : 	er2 :: 32 bits bas                  	*;
;*		er6 :: 32 bits haut                 					*;
;****************************************************;
mulxu.64:
	sub.l	er4,er4
	mov.l	er4,er5
	mov.l	er4,er6

	mov.b	#32,r4l		; charge le nombre de bits de multiplication.	
	andc	#254,ccr
bou64_1:
	rotxr.l	er2			;
	bcc	suite64_1		;
	add.l	er3,er5		;	er5 : H_reg
suite64_1:				;	er6 : L_reg
	rotxr.l	er5			;
	rotxr.l	er6			;
	dec.b	r4l				;
	bne	bou64_1			;
fin64_1:
	mov.l	er6,@_L_reg32_1	;
	mov.l	er5,@_H_reg32_1	;

	mov.l	er6,er2 ;
	mov.l	er5,er6	;
	rts

	.align 1
;****************************************************;
;*         Division 64 Bits / 32 Bits           (2) *;
;*                                                  *;
;* Entrées : @_H_reg32_1 :: nombre 1 (32 bits)      *;
;*           @_L_reg32_1 :: nombre 2 (32 bits)      *;
;*           @_L_reg32_2 :: diviseur (32 bits)      *;
;*                                                  *;
;* Sorties : 	er1 :: 32 bits haut                 *;
;****************************************************;
divxu.64:
	sub.l	er5,er5
	mov.l	@_L_reg32_2,er4	;
	mov.l	@_H_reg32_1,er3 ;
	mov.l	@_L_reg32_1,er2 ;

	cmp.l	#0,er4		; Verifie si le diviseur est à 0.
	beq	div64_6			;
	mov.b	#33,r6l		; charge le nombre de bits de multiplication.	
	andc	#254,ccr
div64_1:	
	bcs	div64_3			;
	cmp.l	er4,er3		;
	bhi	div64_3			;
	beq	div64_3			;
div64_2:
	shll.l	er5			;
	jmp	div64_4			;
div64_3:
	orc	#1,ccr			; Met la carry à 1
	rotxl.l	er5			;
	sub.l	er4,er3		;
div64_4:
	shll.l	er2			;
	rotxl.l	er3			;
	dec.b	r6l				;
	bne	div64_1			;
div64_6:
	mov.l	er5,@_L_reg32_1 ;
	mov.l	er5,@_L_reg32_2 ;
	mov.l	er5,er2					;
	rts

Conclusion :


Pour la multiplication, je l'ai repris d'un livre de Maths App.
Pour la division, Je me suis creusé les meninges (en fait j'ai pas trouvé d'infos)

J'ai aussi fait une extraction de racine carré sur un registre 32 bits, mais très lent... Si l'un de vous à des algo sur le sujet je suis preneur (Pas de virgule flottante/Approximation_succesive, ca m'oblige à recasser tout mon code)... Et oui je suis feignant

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.