Page 1 of 2

Please convert to ASM

Posted: Sat May 30, 2009 2:39 pm
by Wladek
I need translate this code to more fast shape.
This procedures break and including byte

Code: Select all

Procedure Odbierz(liczba.b,numer)
liczba.b+128
a1.d=liczba.b/2
a2.d=Round(a1, #PB_Round_Down)/2
a3.d=Round(a2, #PB_Round_Down)/2
a4.d=Round(a3, #PB_Round_Down)/2
a5.d=Round(a4, #PB_Round_Down)/2
a6.d=Round(a5, #PB_Round_Down)/2
a7.d=Round(a6, #PB_Round_Down)/2
a8.d=Round(a7, #PB_Round_Down)/2

Select numer
Case 1
a=Round(a1, #PB_Round_Up)-Round(a1, #PB_Round_Down)
Case 2
a=Round(a2, #PB_Round_Up)-Round(a2, #PB_Round_Down)
Case 3
a=Round(a3, #PB_Round_Up)-Round(a3, #PB_Round_Down)
Case 4
a=Round(a4, #PB_Round_Up)-Round(a4, #PB_Round_Down)
Case 5
a=Round(a5, #PB_Round_Up)-Round(a5, #PB_Round_Down)
Case 6
a=Round(a6, #PB_Round_Up)-Round(a6, #PB_Round_Down)
Case 7
a=Round(a7, #PB_Round_Up)-Round(a7, #PB_Round_Down)
Case 8
a=Round(a8, #PB_Round_Up)-Round(a8, #PB_Round_Down)
EndSelect 

ProcedureReturn a
EndProcedure

Procedure Wprowadz(liczba.b,numer,wartosc)
liczba.b+128

a1.d=liczba.b/2
a2.d=Round(a1, #PB_Round_Down)/2
a3.d=Round(a2, #PB_Round_Down)/2
a4.d=Round(a3, #PB_Round_Down)/2
a5.d=Round(a4, #PB_Round_Down)/2
a6.d=Round(a5, #PB_Round_Down)/2
a7.d=Round(a6, #PB_Round_Down)/2
a8.d=Round(a7, #PB_Round_Down)/2

c1 = Round(a1, #PB_Round_Up)-Round(a1, #PB_Round_Down)
c2 = Round(a2, #PB_Round_Up)-Round(a2, #PB_Round_Down)
c3 = Round(a3, #PB_Round_Up)-Round(a3, #PB_Round_Down)
c4 = Round(a4, #PB_Round_Up)-Round(a4, #PB_Round_Down)
c5 = Round(a5, #PB_Round_Up)-Round(a5, #PB_Round_Down)
c6 = Round(a6, #PB_Round_Up)-Round(a6, #PB_Round_Down)
c7 = Round(a7, #PB_Round_Up)-Round(a7, #PB_Round_Down)
c8 = Round(a8, #PB_Round_Up)-Round(a8, #PB_Round_Down)

Select numer
Case 1
c1=wartosc
Case 2
c2=wartosc
Case 3
c3=wartosc
Case 4
c4=wartosc
Case 5
c5=wartosc
Case 6
c6=wartosc
Case 7
c7=wartosc
Case 8
c8=wartosc
EndSelect

a=(Pow(2,7)*c8)+(Pow(2,6)*c7)+(Pow(2,5)*c6)+(Pow(2,4)*c5)+(Pow(2,3)*c4)+(Pow(2,2)*c3)+(Pow(2,1)*c2)+c1
a-128

ProcedureReturn a
EndProcedure
Best regards
Wladek

Posted: Sat May 30, 2009 3:03 pm
by Kaeru Gaman
before translating this to ASM to make it faster, you should perhaps slim it the conventional way.

you are using Round() that often, no wonder this function is slow.

I'm curious what this should do, anyway, I can't see right through it yet...

Posted: Sat May 30, 2009 3:20 pm
by Wladek
Thanks- Kaeru Gaman

Posted: Sat May 30, 2009 3:25 pm
by Kaeru Gaman
aaah... ok?

well, my question was:

what are you trying to do with this code?

I don't speak Polish, so I don't know what "Odbierz" and "Wprowadz" mean, and also not "liczba" or "wartosc" .

it seems that you are trying to isolate bits, or put them together.
if that is so, you are going a completely wrong way.

Posted: Sat May 30, 2009 3:36 pm
by cas
Google Translate:

Odbierz = Answer
Wprowadz = Enter
liczba = No.
wartosc = value

Posted: Sat May 30, 2009 3:49 pm
by Wladek
liczba=number
wprowadz=(light interpretation)send
odbierz=recive
wartość=value

Posted: Sat May 30, 2009 3:54 pm
by Wladek
Kaeru Gaman- but
What command is more fast than Round()??

Posted: Sat May 30, 2009 4:51 pm
by Pupil
I'm thinking that you should optimize the algorithm somewhat, as far as i can see this should be enough for the first procedure:

Code: Select all

Procedure Odbierz(liczba.b,numer)
  liczba.b+128
  t0.l = liczba.b >> (numer-1)
  a0.d = t0/2
  t0 = a0
  a = Round(a0, #PB_Round_UP) - t0
ProcedureReturn a
EndProcedure
Please keep in mind that i haven't tested the code because PureBasic is not installed on the computer i'm typing this on.. Maybe it can give you some ideas though..

Posted: Sat May 30, 2009 5:30 pm
by Kaeru Gaman
Wladek wrote:Kaeru Gaman- but
What command is more fast than Round()??
doing it the right way, not using Round() a dozen times were it is probably not needed at all.

thus I asked you what you are trying to achieve.

you are passing a Byte-Value to the Procedure.

so, when you want to divide it by 2, there is no need to make it a Double and then Round it, just rightshift it.

why are you adding 128 in the first place? do you try to eliminate the sign? simply wrong this way.


and after that, what should #PB_Round_Up - #PB_Round_Down do?
to my impression, this would always be 1...

take an arbitrary number with decimals. round it up and round it down, the difference should ALWAYS be 1.

13.4 -> round down: 13 round up: 14 difference: 1

thus, as far I understand what your procedure does...

Code: Select all

Procedure Odbierz(liczba.b,numer) 
ProcedureReturn 1
EndProcedure 
... and I think that is NOT what you want to achieve...

Posted: Sat May 30, 2009 6:08 pm
by Wladek
Kaeru Gaman:
Precedure in not a always return 1

In purebasic all value.b is form -128 to 128.
value.b+128=x
x is form 0 to 256

I try save to byte 8 meaning (true or false )

Posted: Sat May 30, 2009 6:24 pm
by Kaeru Gaman
In purebasic all value.b is form -128 to 128.
value.b+128=x
x is form 0 to 256
nope!
you put it back into a byte, it is still -128 to 127

Code: Select all

For n.l = 0 To 255
  a.b = n
  b.b = a + 128 
  Debug Str(n) + ": " + Str(a) + " +128 = " + Str(b)
Next
I try save to byte 8 meaning (true or false )
AH! an eight-Flag register

... no need at all do go via Double nor use Round just a single time ...

Code: Select all

Procedure.l SetBit( Input.l, Bit.l )
  Protected Result.l
  Protected BitMask.l
  BitMask = 1 << Bit
  Result = Input | BitMask   ; Set one Bit
  ProcedureReturn Result
EndProcedure

Procedure.l ClearBit( Input.l, Bit.l )
  Protected Result.l
  Protected BitMask.l
  BitMask = 1 << Bit
  Result = Input & ( 255 - BitMask )   ; Clear one Bit = keep the others
  ProcedureReturn Result
EndProcedure

Procedure.l ToggleBit( Input.l, Bit.l )
  Protected Result.l
  Protected BitMask.l
  BitMask = 1 << Bit
  Result = Input ! BitMask   ; Toggle one Bit: 1->0   0->1
  ProcedureReturn Result
EndProcedure

Procedure .l TestBit( Input.l, Bit.l )
  Protected Result.l = 0
  Protected BitMask.l
  BitMask = 1 << Bit
  If ( Input & BitMask ) > 0
    Result = 1
  EndIf
  ProcedureReturn Result
EndProcedure

PS:

and as you see, it is THAT short, you don't need a Procedure at all.

just test your flags with single bits...

Code: Select all

Value = Random(255)

Flags.b = Value

Debug "Value = " + Str(Value)

If Flags & 1
  Debug "Flag 1 is Set"
Else
  Debug "Flag 1 is Clear"
EndIf

If Flags & 2
  Debug "Flag 2 is Set"
Else
  Debug "Flag 2 is Clear"
EndIf

If Flags & 4
  Debug "Flag 3 is Set"
Else
  Debug "Flag 3 is Clear"
EndIf

If Flags & 8
  Debug "Flag 4 is Set"
Else
  Debug "Flag 4 is Clear"
EndIf

If Flags & 16
  Debug "Flag 5 is Set"
Else
  Debug "Flag 5 is Clear"
EndIf

If Flags & 32
  Debug "Flag 6 is Set"
Else
  Debug "Flag 6 is Clear"
EndIf

If Flags & 64
  Debug "Flag 7 is Set"
Else
  Debug "Flag 7 is Clear"
EndIf

If Flags & 128
  Debug "Flag 8 is Set"
Else
  Debug "Flag 8 is Clear"
EndIf

Posted: Sat May 30, 2009 6:41 pm
by Wladek
Kaeru Gaman - YES , it is it
Thanks :D

Posted: Sat May 30, 2009 6:49 pm
by Helle
With Assembler:

Code: Select all

Procedure Odbierz(liczba.b, numer)     ;32-Bit
  ;value-range liczba: 0-255, value-range numer: 1-8 
  !MOVZX eax,byte[p.v_liczba]
  !CMP dword[p.v_numer],8    ;if numer is long
  !JNE @f
  !SHR eax,7
  !NOT eax
  !AND eax,1
 ProcedureReturn   ;integer!
  !@@:
  !MOV cl,[p.v_numer]
  !DEC cl
  !SHR eax,cl
  !AND eax,1
 ProcedureReturn   ;integer!
EndProcedure
Gruss
Helle

Posted: Sat May 30, 2009 7:10 pm
by Wladek

Code: Select all

For s = 0 To 8
Debug Str(testbit(50,s))+"      "+Str(Odbierz(50,s+1))
Next s
testbit(50,s) not = Odbierz(50,s+1)[Helle]

Posted: Sat May 30, 2009 7:14 pm
by Michael Vogel
Helle wrote:With Assembler:

Code: Select all

Procedure Odbierz(liczba.b, numer)     ;32-Bit
  ;value-range liczba: 0-255, value-range numer: 1-8 
  !MOVZX eax,byte[p.v_liczba]
  !CMP dword[p.v_numer],8    ;if numer is long
  !JNE @f
  !SHR eax,7
  !NOT eax
  !AND eax,1
 ProcedureReturn   ;integer!
  !@@:
  !MOV cl,[p.v_numer]
  !DEC cl
  !SHR eax,cl
  !AND eax,1
 ProcedureReturn   ;integer!
EndProcedure
Gruss
Helle
Shouldn't...

Code: Select all

For i=1 To 8
	Debug Odbierz(%1010101,i)
Next i
...make a result like 1 0 1 0 1 0 1 0 ?