Re: Question about generated asm

Russell Shaw <[email protected]> Sat, 13 Aug 2016 14:05:42 +1000
Newsgroups gmane.comp.hardware.avr.gcc
Message-ID <[email protected]>
On 13/08/16 11:40, Eric Tang wrote:
> Hi avr-gcc mailing list,
>
> I have a question about the asm generated for C code that sequentially checks
> the bits of an integer in a loop. From what I can gather, during each iteration
> of the loop, the integer is shifted right until the bit to be checked becomes
> the least significant bit of its least significant byte, at which point that bit
> is checked. This seems to be the case both when the loop index counts up and
> when it counts down. I am wondering why the shifting starts over every time, and
> if it would be better to retain the shifted result and shift it one bit more
> every iteration of the loop or to maintain a mask which is used in an AND
> operation with the integer and shifted one bit more during every iteration of
> the loop?
>
> #include <stdint.h>
> #include <avr/io.h>
>
> int main(void)
> {
>      uint8_t temp;
>
>      temp = 0xA5;
>      DDRB |= 0xFF;
>      for (uint8_t i = 0; i < 8; ++i)
>          if (temp & 1 << i)
>              PORTB ^= 0xFF;
>      for (uint8_t i = 8; i--;)
>          if (temp & 1 << i)
>              PORTB ^= 0xFF;
>      return 0;
> }
>
> .file"avr_asm_src.c"
...

You could do something like:

int main(void)
{
     uint8_t temp = 0xA5;
     uint8_t temp_orig = temp;

     DDRB |= 0xFF;
     for (uint8_t i = 0; i < 8; ++i) {
         if (temp & 1)
             PORTB ^= 0xFF;
	temp >>= 1;
     }
     temp = temp_orig;
     for (uint8_t i = 8; i--;) {
         if (temp & 128)
             PORTB ^= 0xFF;
	temp <<= 1;
     }
     return 0;
}