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" __SP_H__ = 0x3e __SP_L__ = 0x3d __SREG__ = 0x3f __tmp_reg__ = 0 __zero_reg__ = 1 .section .text.startup,"ax",@progbits .global main .type main, @function main: /* prologue: function */ /* frame size = 0 */ /* stack size = 0 */ .L__stack_usage = 0 in r24,0x4 ldi r24,lo8(-1) out 0x4,r24 ldi r24,0 ldi r25,0 ldi r20,lo8(-91) ldi r21,0 .L3: movw r18,r20 mov r0,r24 rjmp 2f 1: asr r19 ror r18 2: dec r0 brpl 1b sbrs r18,0 rjmp .L2 in r18,0x5 com r18 out 0x5,r18 .L2: adiw r24,1 cpi r24,8 cpc r25,__zero_reg__ brne .L3 ldi r24,lo8(8) ldi r18,lo8(-91) ldi r19,0 .L4: subi r24,1 brcs .L15 movw r20,r18 mov r0,r24 rjmp 2f 1: asr r21 ror r20 2: dec r0 brpl 1b sbrs r20,0 rjmp .L4 in r25,0x5 com r25 out 0x5,r25 rjmp .L4 .L15: ldi r24,0 ldi r25,0 ret .size main, .-main .ident "GCC: (GNU) 4.9.3" Thanks, Eric
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list