Hi,

I have this simple routine that takes a DWORD and mirrors the bits. (bit 0 swaps with bit 31, bit 1 swaps with bit 30, bit 2 swaps with bit 29... etc...)

I'm almost certain that somebody out there can find a faster, smaller, trickier, or more convoluted way to do it. I look forward to the ideas and discussion that may come of this.

There really isn't any practical use for such an algorithm, except for encryption I suppose, but nonetheless I think it would be fun to play around with.


;  in: eax = dword to mirror

; out: eax = mirrored dword
;
bitMirror proc

mov edx, eax
mov ecx, 32
label:
rol edx, 1
shrd eax, edx, 1
loop label
ret

bitMirror endp


Post your ideas!
Posted on 2002-07-28 14:57:44 by iblis
; reverse neighboring bits

mov edx,eax
and eax,055555555h
and edx,0AAAAAAAAh
shl eax,1
shr edx,1
or eax,edx
; reverse neighboring bit pair
mov edx,eax
and eax,033333333h
and edx,0CCCCCCCCh
shl eax,2
shr edx,2 ; <--- I fix this line
or eax,edx
; reverse neighboring nibbles
mov edx,eax
and eax,00F0F0F0Fh
and edx,0F0F0F0F0h
shl eax,4
shr edx,4
or eax,edx
; reverse bytes
bswap eax
This is from memory - might have messed it up?
But the idea is clear.
This is used in graphics, too.
Posted on 2002-07-28 15:11:17 by bitRAKE
Oh has this topic been posted before?
If it is I am sorry. :(

Interesting code, BitRAKE, thanks. I will play with the idea a bit and see what else I can think of.
Posted on 2002-07-28 15:19:13 by iblis

Oh has this topic been posted before?
If it is I am sorry. :(
I really can't remember.
So, it is good that you bring it up again. :)

0 1 2 3 4 5 6 7 ; start
1-0 3-2 5-4 7-6 ; swap neighbor bits
32-10 76-54 ; swap neighbor pairs of bits
7654-3210 ; swap nibbles (=four bits)

I put a dash between the groups that got swapped.
Posted on 2002-07-28 16:57:59 by bitRAKE
Yeah I understand how it works, thanks. :)

But I can't help but think that there's got to be a simpler way. I'm willing to bet that somebody out there has thought of it. ;)
Posted on 2002-07-28 17:22:19 by iblis
Sorry, there was an error in my typing - I fixed the code. The algorithm works with MMX as well. The only other method that I know of is a look-up table -- which is good if your doing many bytes. Here is the small version from my library:
; reverse 32 bit register (11 bytes)

mov eax,1 ; just lowest bit set
_1: ror edx,1
rcl eax,1
jnc _1
; EAX is bit reversal of EDX
; EDX is preserved
Posted on 2002-07-28 17:24:47 by bitRAKE
Save one clock for another work :)


mov edx,eax
shr eax,1
and edx,055555555h
and eax,055555555h
lea eax,[2*edx+eax]
mov edx,eax
shr eax,2
and edx,033333333h
and eax,033333333h
lea eax,[4*edx+eax]
mov edx,eax
shr eax,4
and edx,0F0F0F0Fh
and eax,0F0F0F0Fh
shl edx,4
add eax,edx
bswap eax

And this code more compressable :)

Using only one register:


i=0
rept 16
test eax,80000000h shr i+1 shl i
jnp @F
xor eax,80000000h shr i+1 shl i
@@: i=i+1
endm

Here used "exchange any two bits" trick.
I am like funny code ;)
Posted on 2002-07-29 13:06:20 by Nexo

Hi,

There really isn't any practical use for such an algorithm, except for encryption I suppose, but nonetheless I think it would be fun to play around with.



Actually i recently helped a friend out with something like this - some machines / controllers require words / bytes etc in this order (non pc based )

so in actual fact there is a use for this :-)
Posted on 2002-07-30 04:16:49 by Terab

And this code more compressable :)
No one else ever mention this on the board besides me - good to know others are thinking about this, too. ;) I like this algo.
Posted on 2002-07-30 07:00:06 by bitRAKE

Oh has this topic been posted before?
If it is I am sorry. :(


In fact, you're the one that posted it before :grin:

http://www.asmcommunity.net/board/index.php?topic=4183&perpage=15&pagenumber=1.msg28829

Thomas
Posted on 2002-08-04 17:26:54 by Thomas
is that way slower or ok?


mov y,eax // 15141312
mov edx,eax
mov ebx,edx
and eax,0000000FFh
shl eax,24
and ebx,0FF000000h
shr ebx,24
or eax,ebx
mov ebx,edx
and ebx,0000FF00h
shl ebx,8
or eax,ebx
mov ebx,edx
and ebx,00FF0000h
shr ebx,8
or eax,ebx
mov z,eax // 12131415

Posted on 2003-09-07 18:24:06 by wizzra

is that way slower or ok?


mov y,eax // 15141312
mov edx,eax
mov ebx,edx
and eax,0000000FFh
shl eax,24
and ebx,0FF000000h
shr ebx,24
or eax,ebx
mov ebx,edx
and ebx,0000FF00h
shl ebx,8
or eax,ebx
mov ebx,edx
and ebx,00FF0000h
shr ebx,8
or eax,ebx
mov z,eax // 12131415

mov eax,y

bswap eax
mov z,eax
...is much faster than your code above. This thread is about something else - the bits have to be reversed as well. :eek:
Posted on 2003-09-07 20:12:59 by bitRAKE
This is almost the same as the first one, but smaller.


push byte 32
pop ecx
bm0: add eax,eax
rcr edx,1
loop bm0
xchg edx,eax
Posted on 2003-09-08 11:09:42 by Sephiroth3
Wow, I don't even remember making this thread.
Posted on 2003-09-08 14:04:31 by iblis