Multiplier pour diviser, nombres magiques

Contenu du snippet

la division est lente par rapport a la multiplication.
On va chercher a définir ce qu'est l'inverse d'un nombre pour le processeur.
Ce nombre est aussi appelé nombre magique.

Source / Exemple :


.NOLIST		
;------ emplacement des déclarations
	.486
	.model flat, stdcall
	option casemap :none   ; case sensitive

	include windows.inc	;
	include kernel32.inc
	include masm32.inc
	include user32.inc
	;------- 	
	includelib kernel32.lib
	includelib masm32.lib
	includelib user32.lib
	Magic_Number PROTO :DWORD

	comment µ
	Explication:
	on prend le problème a l'envers,dans edx on a un nombre = resultat
	de la division de N/D * 2p32 (p = puissance) dans edx
	result = (N/D) * 2p32 ;N= differents entiers 
	N varie et seul D nous interesse	
	On divise les deux membres de l'expression par N 
	1/D = 2p32/D ;-- on vient de definir l'inverse d'un nombre pour le processeur -- 
	;-- en multipliant un nombre par l'inverse du diviseur ,on opère une division --
	;-- par la multiplication ------
	1 0000 0000h = 2p32
	Un registre de 32 bits ne peut contenir qu'un nombre de 2p32 - 1 = FFFF FFFFh
	Pour le processeur,on pose 2p32/D = FFFFFFFFh/D + 1 = magic number		
	µ
	.const
	.data
	hInstance dd 0
	tampAscii db 10 dup (0)
	titre db "Nombre de resultats exacts",0
	.code

	start:
	;---- code here --------
	invoke Magic_Number,325847
	invoke dwtoa,eax,addr tampAscii
	invoke MessageBox,NULL,ADDR tampAscii,addr titre,MB_OK
	invoke ExitProcess,0
;on va diviser par la division puis par la multiplication le nombre passer en
;appel par une suite de nombre de 1 a 10000,on compte le nombre de resultats justes
;la divisision par 1 echoue FFFFFFFFFh +1= -1+1=0
Magic_Number PROC dividende:DWORD     
	Local diviseur:DWORD
	local  result:DWORD
	Local  magic:DWORD
	Local  reste:DWORD
	Local  retour:DWORD
	mov retour,0       ;compteur de resultats corrects
	mov diviseur,1
	;mov dividende,325847
	continue:
		;division normale
		mov edx,0
		mov ecx,diviseur
		mov eax,dividende
		div ecx
		mov result,eax
		mov reste,edx
		;we keep the result for comparison.
		;calcul du nombre magique,FFFFFFFF/D
		;--- on utilise la division pour obtenir le résultat -------
		mov edx,0        
		mov eax,-1
		mov ecx,diviseur
		div ecx
		inc eax
		mov magic,eax
		;connaissant le nombre magique,on procède à la multiplication
		mov edx,0
		mov ecx,magic
		mov eax,dividende
		mul ecx
		.if edx == result	    ;le resultat est dans edx (N/D) * 2p32
			inc retour      ;et non pas eax 
		.endif
		inc diviseur
		.if diviseur != 10001
			jmp continue
		.endif

FindeMagic_Number:
	mov eax,retour
	ret
Magic_Number endp

;################################################################	
	end start

Conclusion :


la méthode peut fonctionner pour n'importe quel dimension de nombre,word qword...

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.