## How to "reverse" a byte?

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

### Re: How to "reverse" a byte?

Honestly, I don't know. I'm not familiar with chess engine coding (or even
how things are done inside).
But the inversion of a whole U/LongInt would really require a huge array.
So, a combination of both, may be the solution.
Luis Babboni
Posts: 303
Joined: Mar 15, 2015 12:41

### Re: How to "reverse" a byte?

"...Thanks to the little-endian versus big-endian war, recent processors have appropriate instructions to swap bytes (ranks) inside a 64-bit word for the reverse arithmetic..."

it refers to "reverse" a 64 bit word bit by bit or to another thing?

What is "a recent" processor?
3622
Posts: 19
Joined: Mar 14, 2015 23:53

### Re: How to "reverse" a byte?

Maybe try a search for bit twiddling (hacks)

https://graphics.stanford.edu/~seander/bithacks.html
MrSwiss
Posts: 3634
Joined: Jun 02, 2013 9:27
Location: Switzerland

### Re: How to "reverse" a byte?

Well, it says Bytes (swapping) ... this is the Endian stuff.
What is referenced here is: ASM instructions.
Luis Babboni wrote:What is "a recent" processor?
This is one of those "undefined" expressions.
The writer probably doesn't know him-/herself.
MrSwiss
Posts: 3634
Joined: Jun 02, 2013 9:27
Location: Switzerland

### Re: How to "reverse" a byte?

The quoted sentence may be misleading. Out of context quotes are like that.
Otherwise:
Byte swap within a Word means actually something different.

A Word (in ASM) is a U/Short (in FB), meaning: there are 4 Words in a 64bit Int.
Therefore, the swap would be: Byte0 with Byte1, Byte2 with Byte3, and so forth ...

Code: Select all

' x64_swap_Word_Bytes.bas -- 2017-01-19, MrSwiss

Union WordBytes
As ULongInt ULInt
Type
As UByte _0
As UByte _1
As UByte _2
As UByte _3
As UByte _4
As UByte _5
As UByte _6
As UByte _7
End Type
End Union

Function swapWordByes(ByVal x As ULongInt) As ULongInt
Dim As WordBytes in, ret
in.ULInt = x

ret._0 = in._1 : ret._1 = in._0
ret._2 = in._3 : ret._3 = in._2
ret._4 = in._5 : ret._5 = in._4
ret._6 = in._7 : ret._7 = in._6

swapWordByes = ret.ULInt
End Function

' ======================
' testig code
Dim As ULongInt a = &hFF007F003F000100, b = swapWordByes(a)

Print "original 'a': "; Hex(a, 16)
Print "swaped 1 'a': "; Hex(swapWordByes(a), 16)
Print
Print "original 'b': "; Hex(b, 16)
Print "swaped 1 'b': "; Hex(swapWordByes(b), 16)

Sleep
greenink
Posts: 200
Joined: Jan 28, 2016 15:45

### Re: How to "reverse" a byte?

the bswap instruction reverses the order of bytes in a 32 bit/64 bit integer. The first byte is swapped with the last, the second with the second last etc. It doesn't reverse the bit order within a byte. It's useful for random number generators, hashing etc.
sancho2
Posts: 547
Joined: May 17, 2015 6:41

### Re: How to "reverse" a byte?

3622 wrote:Maybe try a search for bit twiddling (hacks)

https://graphics.stanford.edu/~seander/bithacks.html

From that site where x is the byte:

Code: Select all

reverse = ((x * &H0802 And &H22110) Or (x * &H8020 and &h88440)) * &H10101 Shr 16

Its fast, but not as fast as the table lookup method.
greenink
Posts: 200
Joined: Jan 28, 2016 15:45

### Re: How to "reverse" a byte?

Code: Select all

for i as ulong=0 to 255
dim as ubyte x=i
print bin(x,8), bin(((x * &H0802 And &H22110) Or (x * &H8020 and &h88440)) * &H10101 Shr 16,8)
next
grindstone
Posts: 755
Joined: May 05, 2015 5:35
Location: Germany

### Re: How to "reverse" a byte?

@Luis Babboni:

I can imagine approximately what you're trying to implement. What exactly is it for? Only to mark the fields the slider can move to? That could be coded in FB quite easy. (Alas, the linked wiki - site isn't accessible at the moment)
greenink
Posts: 200
Joined: Jan 28, 2016 15:45

### Re: How to "reverse" a byte?

Code: Select all

for i as ulong=0 to 255
dim as ubyte x=i
x=((x and &h55) shl 1) or ((x and not &h55) shr 1)
x=((x and &h33) shl 2) or ((x and not &h33) shr 2)
x=((x and &h0f) shl 4) or ((x and not &h0f) shr 4)
print bin(i,8), bin(x,8)
next
3622
Posts: 19
Joined: Mar 14, 2015 23:53

### Re: How to "reverse" a byte?

Code: Select all

screen 18

' 1st Method with 3 operations (64-bit multiply and modulus division)

dim b as ubyte = &B00111011
b=(b * &H0202020202ULL AND &H010884422010ULL) MOD 1023
print bin(b,8)

' 2nd Method with 4 operations (64-bit multiply, no division)

b = &B11011100
b = ((b * &H80200802ULL) AND &H0884422110ULL) * &H0101010101ULL SHR 32
print bin(b,8)

sleep

I3I2UI/I0
Posts: 90
Joined: Jun 03, 2005 10:39
Location: Germany

### Re: How to "reverse" a byte?

@ MrSwiss
mirror8 runs under FB 32/64 Bit
only with 64Bit variables you need 2 versions.

Code: Select all

#Macro mirror64(Variable)
If SizeOf(Variable) = 8 Then
#Ifdef __FB_64BIT__
Asm
mov rax, [Variable]
mov rbx, 0
mov ecx, 64
1:
rcr rax
rcl rbx
dec ecx
jnz 1b
mov [Variable], rbx
End Asm
#Else
Asm
mov eax, [Variable]
mov ebx, 0
mov ecx, 32
1:
rcr eax
rcl ebx
dec ecx
jnz 1b
mov eax, [Variable+4]
mov [Variable+4], ebx
mov ebx, 0
mov ecx, 32
1:
rcr eax
rcl ebx
dec ecx
jnz 1b
mov [Variable], ebx
End Asm
#EndIf
EndIf
#EndMacro

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

Sleep
Luis Babboni
Posts: 303
Joined: Mar 15, 2015 12:41

### Re: How to "reverse" a byte?

grindstone wrote:@Luis Babboni:

I can imagine approximately what you're trying to implement. What exactly is it for? Only to mark the fields the slider can move to? That could be coded in FB quite easy. (Alas, the linked wiki - site isn't accessible at the moment)

I did it using loops, but is a way too slow.
MrSwiss
Posts: 3634
Joined: Jun 02, 2013 9:27
Location: Switzerland

### Re: How to "reverse" a byte?

@I3I2UI/I0,

we seem to be talking about two different things here:
YOU: different TREATMENT (this is correct, in itself)
ME: different register NAMING (32-EAX vs. 64-RAX)
If you're using EAX on a x64-CPU, you'll get a ASM-Error:
similar to "wrong word size, dword instead of qword" (even with push/pop).
One could only replace it, with: RAD (RAX - low dword).

Therefore, FB bits check, should be replaced with a CPU check!
(The SizeOf(Variable) check, must remain.)
I3I2UI/I0
Posts: 90
Joined: Jun 03, 2005 10:39
Location: Germany

### Re: How to "reverse" a byte?

MrSwiss wrote:If you're using EAX on a x64-CPU, you'll get a ASM-Error:
similar to "wrong word size, dword instead of qword" (even with push/pop).
One could only replace it, with: RAD (RAX - low dword).
Of course, I can also use in FB64 eax, ax, ah, al as a register without ASM-Error.
FB1050_64

Code: Select all

'dies laeft unter FB64 und FB32
#Macro mirror64(Variable)
If SizeOf(Variable) = 8 Then
Asm
mov eax, dword Ptr[Variable]
mov ebx, 0
mov ecx, 32
1:
rcr eax
rcl ebx
dec ecx
jnz 1b
mov eax, dword Ptr[Variable+4]
mov dword Ptr[Variable+4], ebx
mov ebx, 0
mov ecx, 32
1:
rcr eax
rcl ebx
dec ecx
jnz 1b
mov dword Ptr[Variable], ebx
End Asm
EndIf
#EndMacro

MrSwiss wrote:Therefore, FB bits check, should be replaced with a CPU check!
FB 64bit needs a 64bit System -> 64bit CPU, therefore, no CPU check!