Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reverse a byte

I am currectly working on a project and it happens that I have to reverse the order of a byte. I am currently using AVR Studio Mega32 Microcontroller.

For example:

0000 0001 becomes 1000 0000
0001 0110 becomes 0110 1000
1101 1001 becomes 1001 1011

To start I have this:

ldi r20,0b00010110

What is the easiest way to reverse the byte so that r20 becomes 01101000?

like image 852
stefana Avatar asked Mar 15 '13 10:03

stefana


People also ask

How do you reverse bytes in Java?

The java. lang. Integer. reverseBytes() method returns the value obtained by reversing the order of the bytes in the two's complement representation of the specified int value.

How do you reverse a bit in C++?

Reverse Bits in C++ answer := answer OR (n AND i), and shift it to the left i times. n := n after right shifting 1 bit.


3 Answers

Here's a snippet - it's written for the GNU toolchain (avr-gcc, binutils, avr-libc, etc) - but it should be easy to adapt:

static inline __attribute__ ((always_inline))
uint8_t avr_reverse_byte (uint8_t x)
{
    x = ((x & 0x55) << 1) | ((x & 0xaa) >> 1);
    x = ((x & 0x33) << 2) | ((x & 0xcc) >> 2);

    /* x = ((x & 0x0f) << 4) | ((x & 0xf0) >> 4); */

    __asm__ ("swap %0" : "=r" (x) : "0" (x)); /* swap nibbles. */

    return x;
}

So, not much of an improvement over the 'C' code, except for the final hi-lo nibble swap implemented with the swap instruction.

like image 190
Brett Hale Avatar answered Oct 26 '22 22:10

Brett Hale


I can't provide AVR code just now. But the general bit reversing technique is following:

abcd efgh   p
badc fehg   p = ((p and 0AAh) shr 1) or ((p shl 1) and 0AAh)
dcba hgfe   p = ((p and 033h) shr 2) or ((p shl 2) and 033h)
hgfe dcba   p = ((p and 00Fh) shr 4) or ((p shl 4) and 0F0h)
like image 42
johnfound Avatar answered Oct 27 '22 00:10

johnfound


Another easy way is to use the carry flag:

Repeat 8x:

lsl r20 ; shift one bit into the carry flag
ror r0  ; rotate carry flag into result 

(Input in r20, output in r0, content of r20 destroyed; registers may be changed freely.)

This uses 16 instructions @ 2 bytes, 1 cycle each = 32 bytes of program memory and 16 cycles to reverse one byte when completely 'unrolled'. Wrapped in a loop, the code size can be reduced but execution time will increase.

like image 31
JimmyB Avatar answered Oct 27 '22 00:10

JimmyB