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;
}