How to "reverse" a byte?

New to FreeBASIC? Post your questions here.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: How to "reverse" a byte?

Post by MrSwiss »

You might as well use my ASM-Macro, which btw. runs on x32 as well as x64.
It mirrors a whole ULongInt at once (bit by bit):

Code: Select all

#Macro mirror64(Variable)
If SizeOf(Variable) = 8 Then
  #Ifdef __FB_64BIT__
    Asm
        mov rax, qword Ptr[Variable]
        Xor rbx, rbx ' faster than: mov rbx, 0
        mov rcx, 64
      1:
        rcr rax
        rcl rbx
        dec rcx
        jnz 1b
        mov qword Ptr[Variable], rbx
    End Asm
  #Else
    Asm
        mov eax, dword Ptr[Variable]
        Xor ebx, ebx ' mov ebx, 0
        mov ecx, 32
        mov edx, ecx ' save it to unused reg (for next run)
      1:
        rcr eax
        rcl ebx
        dec ecx
        jnz 1b
        mov eax, dword Ptr[Variable + 4]
        mov dword Ptr[Variable + 4], ebx
        Xor ebx, ebx ' mov ebx, 0
        mov ecx, edx ' restore '32'
      2:             ' <--- diff. label
        rcr eax
        rcl ebx
        dec ecx
        jnz 2b
        mov dword Ptr[Variable], ebx
    End Asm
  #EndIf
EndIf
#EndMacro

Dim As ULongInt zahl = &h2233445566778899
Print Bin(zahl, 64), Hex(zahl, 16)
mirror64(zahl)
Print Bin(zahl, 64), Hex(zahl, 16)
mirror64(zahl)
Print Bin(zahl, 64), Hex(zahl, 16)

Sleep
The endian swapping (ASM-Macro for both compilers), has also been posted by me: earlier in this thread.

@Luis,
now, you just have to decide, which one is the *one for you*.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: How to "reverse" a byte?

Post by Luis Babboni »

For the moment, thinking I do not need more speed right now, I´ll go for the FB that I understand a little more than assembler (my only experience in assembler was in 1987 with my Sinclair Spectrum making a Tetris and a 3d labyrinth!!!)
Any way I feel, if I finally use it, is the first time I feel Soberango will have some code directly made from others and I want to thanks you and other briefly (just mentioning the nicknames) on its webpage. Could I?

I said "...if I finally use it..." I´m still from from that. For the moment I just solved horizontal rooks captures. The hard part seems to be vertical rook captures and diagonal bishops captures (queens must be just a sum of rook and bishop and knights and pawns seems simplier)

Actually I need to ask more questions that I´ll do below.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: How to "reverse" a byte?

Post by Luis Babboni »

Representing the position of a piece in a chessboard as the only 1 in a 64 bits byte, I could move that piece using shl or shr...
my question now is that seems that when I go higher than bit 63 or lower than bit 0.... the 1 do not appear on the other side!!! :-O
Looks nice for my purpose.... but could I modified another byte of the RAM making some not wanted mess?
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: How to "reverse" a byte?

Post by MrSwiss »

Luis Babboni wrote:when I go higher than bit 63 or lower than bit 0.... the 1 do not appear on the other side!!! :-O
Looks nice for my purpose.... but could I modified another byte of the RAM making some not wanted mess?
No, shifting only takes place within the number of Bytes specified, by the Variable (ULongInt = 8 x Byte,
ULong = 4 Byte etc.). Also, when you are doing a shl then, there are bit's lost by the shifting amount (to
the left), replaced by ZERO's on the right hand side. (this applies vice versa, on a shr)

Example: just using a single Byte
&b11111111 shl 7 = &b10000000
&b11111111 shl 3 = &b11111000 (and so on)
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: How to "reverse" a byte?

Post by grindstone »

MrSwiss wrote:The endian swapping (ASM-Macro for both compilers), has also been posted by me: earlier in this thread.
Please don't get me wrong. My intention was only to show the speed difference between FB and ASM (ASM is twice as fast).
Luis Babboni wrote:Any way I feel, if I finally use it, is the first time I feel Soberango will have some code directly made from others and I want to thanks you and other briefly (just mentioning the nicknames) on its webpage. Could I?
For my part, I have no objections. :-)
Luis Babboni wrote:The hard part seems to be vertical rook captures and diagonal bishops captures
Not at all. For diagonal captures you got the function diagonalAttacks, and for vertical captures there's the analouge function fileAttacks (if you might ask me for a transcoding, here you are).

Code: Select all

Dim Shared As ULongInt aFileAttacks(0 To 7, 0 To 63) '4 KByte
Const As ULongInt aFile   = &h0101010101010101
Const As ULongInt diac2h7 = &h0080402010080400

Function fileAttacks(occ As ULongInt, sq As ULong) As ULongInt
	occ = aFile  And (occ Shr (sq And 7))
	occ = (diac2h7 *  occ ) Shr 58
	Return aFileAttacks(sq Shr 3,occ Shl (sq And 7))
End Function
Luis Babboni wrote:bishop and knights and pawns seems simplier
Writing my human2 pseudo - engine I perceived especially the pawn handling as difficult.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: How to "reverse" a byte?

Post by Luis Babboni »

Thanks grindstone.....trying to understand your posted code now... I couldn´t for the moment :-D
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: How to "reverse" a byte?

Post by Luis Babboni »

Mmm, sorry grindstone... I need some examples to see how diagonalAttacks and fileAttacks works. :-(

EDIT: mmmm, is needed to complete long number of data (the diagonals, antidiagonals, etc) to could make an example. Let me fight alone for a while. I´ll ask for help soon anyway I´m afraid! :-D
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Re: How to "reverse" a byte?

Post by Stonemonkey »

Just looking for alterative methods out of curiosity, this throws up some warnings about truncating values in 32bit FB (EDIT: fixed)but still seems to work (is ok when doing 32 bits, maybe ok doing 64 bits in 64bit FB)
Probably a bit slow due to multiplys and the 64bit ops on 32 bit machines.

Code: Select all

#macro reverse64(r)
r xor=(((r shr 1)xor r)and &h5555555555555555ull)*3
r xor=(((r shr 2)xor r)and &h3333333333333333ull)*5
r xor=(((r shr 4)xor r)and &h0f0f0f0f0f0f0f0full)*17
r xor=(((r shr 8)xor r)and &h00ff00ff00ff00ffull)*257
r xor=(((r shr 16)xor r)and &h0000ffff0000ffffull)*65537
r xor=(((r shr 32)xor r)and &h00000000ffffffffull)*4294967297
#endmacro

dim as ulongint a=&b0111110111101110110101111111101111111011111101111101111011101101

print bin$(a,64)
reverse64(a)
print bin$(a,64)

sleep
in 64 bit assembly it might be something like this, don't know the exact instructions and cant test it myself.

Code: Select all

#macro reverse64bits_asm64(r)
asm
    mov rax,[r]
    mov rbx,rax
    shr rbx,1
    xor rbx,rax
    and rbx,&h5555555555555555
    imul rbx,3
    xor rax,rbx
    mov rbx,rax
    shr rbx,2
    xor rbx,rax
    and rbx,&h3333333333333333
    imul rbx,5
    xor rax,rbx
    mov rbx,rax
    shr rbx,4
    xor rbx,rax
    and rbx,&h0f0f0f0f0f0f0f0f
    imul rbx,17
    xor rax,rbx
    bswap rax
    mov [r],rax
end asm
#endmacro
and 32 bit assembly

Code: Select all

#macro reverse64bits_asm32(r)
asm
    mov eax,[r]
    mov ecx,[r+4]
    
    mov ebx,eax
    mov edx,ecx
    shr ebx,1
    shr edx,1
    xor ebx,eax
    xor edx,ecx
    and ebx,&h55555555
    and edx,&h55555555
    imul ebx,3
    imul edx,3
    xor eax,ebx
    xor ecx,edx
    
    mov ebx,eax
    mov edx,ecx
    shr ebx,2
    shr edx,2
    xor ebx,eax
    xor edx,ecx
    and ebx,&h33333333
    and edx,&h33333333
    imul ebx,5
    imul edx,5
    xor eax,ebx
    xor ecx,edx
    
    mov ebx,eax
    mov edx,ecx
    shr ebx,4
    shr edx,4
    xor ebx,eax
    xor edx,ecx
    and ebx,&h0f0f0f0f
    and edx,&h0f0f0f0f
    imul ebx,17
    imul edx,17
    xor eax,ebx
    xor ecx,edx
    bswap eax
    bswap ecx
    
    mov [r+4],eax
    mov [r],ecx
end asm
#endmacro
Last edited by Stonemonkey on Jan 24, 2017 23:03, edited 1 time in total.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: How to "reverse" a byte?

Post by Luis Babboni »

It seems I got it for diagonals!! :-)
vdecampo
Posts: 2992
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Re: How to "reverse" a byte?

Post by vdecampo »

Late to the party but I found this....

Code: Select all

Function Rev(in As UInteger) As UInteger   

   ' swap odd and einen bits   
   in = ((in Shr 1) and &h55555555) or ((in and &h55555555) Shl 1)
   ' swap consecutiine pairs
   in = ((in Shr 2) And &h33333333) Or ((in And &h33333333) Shl 2)
   ' swap nibbles ... 
   in = ((in Shr 4) And &h0F0F0F0F) Or ((in And &h0F0F0F0F) Shl 4)
   ' swap bytes
   in = ((in Shr 8) And &h00FF00FF) Or ((in And &h00FF00FF) Shl 8)
   ' swap 2-byte long pairs
   in = ( in Shr 16 )               Or ( in Shl 16)

   Return in
   
End Function

Dim in As UInteger ' 32 bit word to reinerse bit order
in = &b00011010
Print Bin(in,32), Bin(Rev(in),32)

Sleep
-Vince
Post Reply