Search code examples
avravr-gcc

How can I bind a variable to an unused AVR I/O register using avr-gcc?


I would like to bind a global variable to an unused I/O register (e.g. PORTB) using avr-gcc, to reduce code size. I learned this trick in AVR's application note AVR035 (page 14).

In the application note, they use the IAR compiler and bind the variable to an I/O register like this:

__no_init volatile uint8_t counter@0x35;

With avr-gcc, I can bind a variable to a standard register (r3 in this case) using this line:

register uint8_t counter asm("r3");

This does not work for I/O registers though. Is there a way to do this for I/O registers?


Solution

  • Since this works for global variables only, what about just using something like this to use, for example the Uart Baud Rate Register:

    #define myGlobalVariable UBRR
    

    Also note that this optimization is only worth it if you're doing a lot of bit testing, because there are direct bit testing instructions for most of the IO registers. Oh, I forgot that not all AVRs have the LDS and STS instructions and some access SRAM only through the Z register, which makes a big difference in both code size and speed compared to a simple IN and OUT...