! SAR Eax,8

Pour discuter de l'assembleur
kelly
Messages : 176
Inscription : jeu. 09/sept./2004 16:15

! SAR Eax,8

Message par kelly »

J'en ai marre... :x

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 :!:
kelly
Messages : 176
Inscription : jeu. 09/sept./2004 16:15

Message 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 8) 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.
fweil
Messages : 505
Inscription : dim. 16/mai/2004 17:50
Localisation : Bayonne (64)
Contact :

Message 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
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.
kelly
Messages : 176
Inscription : jeu. 09/sept./2004 16:15

Message 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
fweil
Messages : 505
Inscription : dim. 16/mai/2004 17:50
Localisation : Bayonne (64)
Contact :

Message 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
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.
kelly
Messages : 176
Inscription : jeu. 09/sept./2004 16:15

Message 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 ?
fweil
Messages : 505
Inscription : dim. 16/mai/2004 17:50
Localisation : Bayonne (64)
Contact :

Message 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
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.
kelly
Messages : 176
Inscription : jeu. 09/sept./2004 16:15

Message par kelly »

Ca y est, j'ai trouvé mon bug. Trop heureuse =)
fweil
Messages : 505
Inscription : dim. 16/mai/2004 17:50
Localisation : Bayonne (64)
Contact :

Message 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.
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.
kelly
Messages : 176
Inscription : jeu. 09/sept./2004 16:15

Message 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]
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

A quoi sert ce code, sans indisc? :P
kelly
Messages : 176
Inscription : jeu. 09/sept./2004 16:15

Message 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.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message 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.
Répondre