Loops are widely used in 8-bit AVR code. There are "while ( ) { }" loop, "for ( )" loop, and "do { } while ( )" loop. If the -Os optimization option is enabled, the compiler will optimize the loops automatically to have the same code size.
However, we can still reduce the code size slightly. If we use a "do { } while ( )" loop, an increment or a decrement loop index generates different code size. Usually we write our loops counting from 0 to the maximum value (increment), but it is more efficient to count the loop from the maximum value to 0 (decrement).
That is because in an increment loop, a comparison instruction is needed to compare the loop index with the maximum value in every loop to check if the loop index reaches the maximum value.
When we use a decrement loop, this comparison is not needed any more because the decremented result of the loop index will set the Z (zero) flag in SREG if it reaches zero.
Table 1 shows the effect of "do { } while ( )" loop with increment and decrement loop index.
Do{ }While( ) with increment loop index | Do{ }While( ) with decrement loop index | |
---|---|---|
C source code |
#include <avr/io.h> int main(void) { uint8_t local_1 = 0; do { PORTB ^= 0x01; local_1++; } while (local_1<100); } |
#include <avr/io.h> int main(void) { uint8_t local_1 = 100; do { PORTB ^= 0x01; local_1--;(1) } while (local_1); } |
AVR Memory Usage |
Program: 96 bytes (1.2% Full) (.text + .data + .bootloader) Data: 0 bytes (0.0% Full) (.data + .bss + .noinit) |
Program: 94 bytes (1.1% Full) (.text + .data + .bootloader) Data: 0 bytes (0.0% Full) (.data + .bss + .noinit) |
Compiler optimization level | -Os (Optimize for size) | -Os (Optimize for size) |