Page 1 sur 1
! SAR Eax,8
Publié : ven. 05/août/2005 22:58
par kelly
J'en ai marre...
Ce code n'arrive pas a mettre la valeur Eax/256 dans "Re" :
Code : Tout sélectionner
!MOV dword Ecx,[a_noeud]
!ADD dword Ecx,[v_u]
!push Ecx
!MOV Eax,[Ecx]
!MOV dword Edx,[v_np]
!MUL Edx
!MOV dword Ecx,[v_re]
!ADD Eax, Ecx
!POP Ecx
!MOV byte [Ecx],Al
!SAR Eax,8
!MOV dword [v_re],Eax
Vous me confirmez bien que si je fait un "SAR Eax,8", ca fait tourner les bits sur tout le registre Eax et pas sur la partie haute et la partie basse (ax) de facon independante ??
Ce code fonctionne mais il pose un probleme de lenteur avec la partie "si xx<0 alors on fait xx+256" tandis qu'en assembleur, je "MUL" sans m'occuper du signe. Et ce code a aussi un bleme d'overflow car XX(max 255)*NP(je ne peux pas aller a plus de 8 millions)+RE me limite !
Ce code est celui ci et il fonctionne :
Code : Tout sélectionner
xx=noeud(u)
If xx<0
xx+256
EndIf
xx*np+re
If xx>255
re=xx/256
xx-re*256
Else
re=0
EndIf
noeud(u)=xx
Ca me casse la tête et j'ai pas besoin de ca

Publié : ven. 05/août/2005 23:10
par kelly
ps : mon probleme viendrait de ca ? :
Les instructions de rotations et décalages, ROL et ROR (rotation circulaire à gauche et à droite, ROR rotation left, ROR rotation right), RCL et RCR (décalage avec CF entrant), SHL et SHR (décalage avec 0 entrant, SHL et SHR équivalent donc à RCL et RCR si CF=0, shift left et shift right) et enfin SAR (décalage à droite avec réinjection du bit de signe, shift arithmétique right) ne positionnent que CF qui représente donc le bit sortant du décalage. À noter qu'il n'y a que 7 types de rotations et décalages (et non

car SAR n'a pas sa réplique à gauche (le très gentil tasm32 accepte cependant l'instruction SAL mais le convertit en SHL sans autre forme de procès). En effet, s'il est signifiant de réinjecter le bit de signe i.e. le bit le plus à gauche sur un décalage à droite, il n'est pas signifiant de réinjecter le bit 0 sur un décalage à gauche. SAR permet de diviser par deux en maintenant le signe tel quel, si donc la valeur était négative (en considérant le complément à 2), elle restera négative après SAR car le bit de signe a été réinjecté. À noter que s'agissant des rotations et décalages, on a le choix entre l'exécuter une seule fois (e.g. ROR AL,1) ou CL fois (e.g. ROR AL,CL), dans ce cas bien sûr il faut renseigner CL par un mov juste avant par exemple MOV CL,3, ce qui aura pour effet de faire exécuter trois fois le décalage ou la rotation.
Publié : ven. 05/août/2005 23:33
par fweil
Kelly,
Vous me confirmez bien que si je fait un "SAR Eax,8", ca fait tourner les bits sur tout le registre Eax et pas sur la partie haute et la partie basse (ax) de facon independante ??
Oui !
Par contre, moi je ne peux pas t'aider avec le bout de code hors du contexte ... si tu ajoutes un minimum autour pour montrer ce que doit donner le code dans son contexte (avec une boucle et des valeurs initiales pour les variables et les éléments du tableau), je peux regarder de plus près.
Slts
Publié : sam. 06/août/2005 0:45
par kelly
Ca, ca marche :
Code : Tout sélectionner
nb=100
look.b
Dim noeud.b(nb)
noeud(0)=1
xx.l=0
re.l=0
For np=2 To 8
u=0
Repeat
xx=noeud(u)
If xx<0
xx+256
EndIf
xx*np+re
If xx>255
re=xx/256
xx-re*256
Else
re=0
EndIf
noeud(u)=xx
u+1
Until u>=100
Next
Debug noeud(0)
Debug noeud(1)
Debug noeud(2)
Debug noeud(3)
; le vrai resultat est 40320
; donc :
; noeud(0)=-128
; noeud(1)=-99
; noeud(2)=0
; noeud(3)=0
Ca, ca ne marche pas ("re" se choppe parfois une valeur !) :
Code : Tout sélectionner
nb=100
look.b
Dim noeud.b(nb)
noeud(0)=1
xx.l=0
re.l=0
For np=2 To 8
u=0
Repeat
!MOV dword Ecx,[a_noeud]
!ADD dword Ecx,[v_u]
!push Ecx
!MOV Eax,[Ecx]
!MOV dword Edx,[v_np]
!MUL Edx
;
!MOV dword Ecx,[v_re]
!ADD Eax, Ecx
;
!POP Ecx
!MOV byte [Ecx],Al
;
!SAR Eax,8
!MOV dword [v_re],Eax
u+1
Until u>=100
Next
Debug noeud(0)
Debug noeud(1)
Debug noeud(2)
Debug noeud(3)
; le vrai resultat est 40320
; donc :
; noeud(0)=-128
; noeud(1)=-99
; noeud(2)=0
; noeud(3)=0
Publié : sam. 06/août/2005 1:11
par fweil
Est-ce que celà répond au bon fonctionnement ?
Code : Tout sélectionner
nb = 100
look.b
Dim noeud.b(nb)
noeud(0) = 1
xx.l = 0
re.l = 0
For np = 2 To 8
u = 0
Repeat
! MOV ebx,dword [v_u] ; xx = noeud(u)
! MOV ebp,dword [a_noeud]
! MOVSX eax,byte [ebp+ebx]
! MOV dword [v_xx], eax
! ADD dword [v_xx], 256 ; xx + 256
! And dword [v_xx], 255 ; xx % 256
! MOV ebx,dword [v_xx] ; xx * np + re
! IMUL ebx,dword [v_np]
! ADD ebx,dword [v_re]
! MOV dword [v_xx],ebx
! MOV ebx,dword [v_xx] ; re = xx / 256
! SAR ebx, 8
! MOV dword [v_re], ebx
! And dword [v_xx], 255 ; xx % 256
! PUSH dword [v_xx] ; noeud(u) = xx
! MOV ebx,dword [v_u]
! POP eax
! MOV byte [ebp+ebx],al
! INC dword [v_u] ; u + 1
Until u => 100
Next
Debug noeud(0)
Debug noeud(1)
Debug noeud(2)
Debug noeud(3)
End
Publié : sam. 06/août/2005 2:28
par kelly
Apparement oui, ta routine marche.
Il est vrai qu'elle est plus longue mais qu'importe. C'est surtout que j'en apprendrais beaucoup si l'on m'expliquait ce qui provoquait une erreur dans mon code !!!
Dis moi, je me suis appercue que "re" dans ma routine etait parfois negatif. Hors, cela ne se peut pas normalement.
L'instruction "SAR" peut créer un nombre negatif ????
Pourtant, si le bit de poids fort est mis, il devrait tourner et faire passer le nombre en positif, non ???
Autre chose, peut tu me dire combien peut avoir au maximum ma valeur "np" pour ta routine avant qu'il y ait une erreur de calcul sans qu'il y ait pour autant de bug ?
Publié : sam. 06/août/2005 2:43
par fweil
A priori le problème vient de ce que tu ne rajoutes pas 256 quand la valeur xx est négative :
!MOV dword Ecx,[a_noeud] ; ecx = @noeud()
!ADD dword Ecx,[v_u] ; ecx = @noeud(u)
!push Ecx
!MOV Eax,[Ecx] ; eax = noeud(u)
!ADD eax, 256
!AND eax, 255
!MOV dword Edx,[v_np] ; edx = np
!iMUL Edx ; edx * accumulator
;
!ADD Eax, dword [v_re] ; eax + re
;
!POP Ecx
!MOV byte [Ecx],Al ; noeud(u) = al
;
!SAR Eax,8 ; eax / 256
!MOV dword [v_re],Eax ; re = eax
Publié : sam. 06/août/2005 12:47
par kelly
Ca y est, j'ai trouvé mon bug. Trop heureuse =)
Publié : sam. 06/août/2005 15:08
par fweil
... après vérification, dans l'algo qui fonctionne re n'a jamais de valeur négative ... selon ce que je vois sur mon PC.
Publié : dim. 07/août/2005 13:36
par kelly
Voila mon code corrigé :
Code : Tout sélectionner
!MOV dword Ecx,[a_noeud]
!ADD dword Ecx,[v_u]
!push Ecx
!XOR Eax, Eax
!MOV Al, [Ecx]
!MOV dword Edx,[v_np]
!MUL Edx
;
!MOV dword Ecx,[v_re]
!ADD Eax, Ecx
!POP Ecx
!MOV byte [Ecx],Al
!SHR Eax,8
!MOV dword [v_re],Eax
!INC dword [v_u]
Tout résidait ici :
!XOR Eax, Eax
!MOV Al, [Ecx]
Publié : lun. 08/août/2005 14:44
par djes
A quoi sert ce code, sans indisc?

Publié : sam. 13/août/2005 0:26
par kelly
a prendre un octet dans une bank (un dim) et a multiplier cet octet par un nombre, puis a replacer le resultat en paquet d'octets dans la bank.
Publié : lun. 15/août/2005 19:35
par djes
Euh oui, ça j'avais vu, lol! Je crois que je suis trop indiscret

. Si tu veux aller plus vite, tu peux peut-être utiliser les instructions mmx.