MULTIPLIER POUR DIVISER, NOMBRES MAGIQUES

ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 - 4 oct. 2012 à 08:29
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 - 12 déc. 2012 à 17:48
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/54635-multiplier-pour-diviser-nombres-magiques

ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
12 déc. 2012 à 17:48
La réponse est içi avec le code source.
http://win32assembly.programminghorizon.com/files/magicnumber.zip.
Même résultat que le code de brunews et la même limitation a des nombres de 29 bits,a cause du décalage de trois.
Max:1fffffffh
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
10 déc. 2012 à 09:01
citation:
Si on veut vraiment coder obsolete, il reste a transposer "div r10" de bnRecidivDW(), c'est quand meme pas la mer à boire pour un codeur ASM.

Voici donc le code:
; void bnRecidivDW(ECX DWORD v, RDX LPBNRECIDIV prcdvs)
ALIGN 16
bnRecidivDW PROC
mov r10d, ecx
mov r9, rdx ; R9 = prcdvs
xor ecx, ecx ; pour result coherent de BSR
lea r8d, [r10d - 1]

bsr ecx, r10d
test r8d, r10d
mov [r9 + 8], ecx ; prcdvs->decSHR IMPEC
mov eax, 1
je short POWEROF2
shl eax, cl

shl rax, 32
xor edx, edx
div r10

add eax, 1
xor ecx, ecx ; NON pow2
mov [r9], eax ; prcdvs->loMagic
POWEROF2:
mov [r9 + 12], ecx
ret 0
bnRecidivDW ENDP

;-------------------------------------------------------------
SANS COMMENTAIRES
;-------------------------------------------------------------
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
9 déc. 2012 à 13:14
mais enfin, on n'est pas sur telecharger.com, je donne l'algo et travaille qui veut.

Je tape 13 en zone DWORD, prog donne:
mov eax, dividend
mov ecx, -1651910498
mul ecx
shr edx, 3
EDX = RESULT

C'est pas du 32 bits ?
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
9 déc. 2012 à 10:54
Clair que le soft est en x64, nous sommes fin 2012.

Tu ne vois pas que la zone DWORD fait le 32 bits ?

Si on veut vraiment coder obsolete, il reste a transposer "div r10" de bnRecidivDW(), c'est quand meme pas la mer à boire pour un codeur ASM.
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
9 déc. 2012 à 10:20
Ce qui serait sympa , c'est de répondre à la question du 32 bits ,je ne vois que du 64 bits !,Inutilisable dans ce cas.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
8 déc. 2012 à 20:58
ok nos échanges m'ont décidé, je l'ai mis en source.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
8 déc. 2012 à 20:38
Un de ces jours je mettrai le code de mon utilitaire.

En attendant, il ne faut pas prendre mal quand on signale qu'un code n'est pas au point.
M'est deja arrivé sur cppfrance, j'ai retiré le code défectueux et je m'entends très bien avec celui qui me l'avait signalé.
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
8 déc. 2012 à 18:29
Ce qui manque est la formule générale pour trouver tous les nombres magiques.1/FFFFFFFFh nombres possibles ne fait pas avancer beaucoup le problème !.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
8 déc. 2012 à 08:44
mov eax, dividend
mov ecx, -858993459
mul ecx
shr edx, 3
EDX = RESULT

Voila le calcul du divInv de 10, il n'y a rien d'autre à écrire dans un prog.
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
7 déc. 2012 à 19:08
11e1a301 au lieu de 11e1a300 ce qui montre que le calcul par nombre magique dans certains cas,fait un arrondi à l'unité supérieure quand le reste atteint diviseur -1 (içi 9).
Ce n'est pas un résultat faux.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
6 déc. 2012 à 19:02
J'ai mis une version en telechargement:
http://www.brunews.com/
section freewares, ReciDiv x64
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
3 déc. 2012 à 12:16
Salut,

ton code:
mov edx,0
mov eax,-1
mov ecx,diviseur
div ecx
inc eax

qui donnerait donc:
invDiv(10) = 429496730

Testons un DVDND = 3000000008:EDX:EAX 3000000008 * 429496730 1288490193435973840EDX 300000001 FAUX

J'ai fait une erreur ?
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
4 oct. 2012 à 08:37
Une autre maniere de voir le problème:
Les grands nombres sont définis par plusieurs registres:
EDX:EAX (edx poids forts,eax poids faibles)
On souhaite utiliser l'inverse de 250 = 0,004
On ne peut pas utiliser ce résultat a cause de la virgule,
il faudrait changer de format de nombre et on veut rester dans le domaine des entiers et des registres.
On multiplie donc ce résultat par le contenu d'un registre soit:
2p32 - 1 FFFF FFFFh 4294967295
Ceci a pour effet de decaler le resultat dans edx,les poids forts
0,004 * 4294967295 = 17179869,18 <= 17179870 = 10624DEh
si on multiplie un nombre par 10624DEh et qu'on recueuille le resultat dans edx,on tient le resultat d'une division par 250.
Conclusion:
plus de magie