How to flip a byte

I work on the project correctly, and it happens that I have to reverse the byte order. I am currently using the AVR Studio Mega32 microcontroller.

For instance:

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

To get started, I have the following:

 ldi r20,0b00010110 

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

+4
source share
3 answers

Here is a snippet - it was written for the GNU toolchain (avr-gcc, binutils, avr-libc, etc.), but it is 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; } 

Thus, there are not many improvements over the "C" code, with the exception of the final hi-lo nibble replacement implemented with the swap command.

+2
source

I can’t provide the AVR code just now. But the general method for reversing bits is as follows:

 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) 
+1
source

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 to r20 , output to r0 , contents of r20 destroyed, registers can be changed freely.)

This uses 16 instructions @ 2 bytes, 1 cycle each = 32 bytes of program memory and 16 cycles to undo one byte when it is fully "expanded". The code size wrapped in a loop can be reduced, but the execution time will increase.

+1
source

Source: https://habr.com/ru/post/1469470/


All Articles