cmicrocontrolleravrram

AVR C compilers behavior. Memory management


Do AVR C compilers make program memorize the address in SRAM where function started to store its data (variables, arrays) in data stack in one of index registers in order to get absolute address of local variable by formula:

absoluteAdr = functionDataStartAdr + localShiftOfVariable.

And do they increase data stack point when variable declared by it's length or stack pointer increased in end/start of function for all it's variables lengths.


Solution

  • Let's have a look at avr-gcc, which is freely available including its ABI:

    Do AVR C compilers make program memorize the address in SRAM where function started to store its data (variables, arrays) in data stack in one of index registers in order to get absolute address of local variable by formula:

    Yes, no, it depends:

    Static Storage

    For variables in static storage, i.e. variables as defined by

    unsigned char func (void)
    {
        static unsigned char var;
        return ++var;
    }
    

    the compiler generates a symbol like var.123 with appropriate size (1 byte in this case). The linker / locator will then assign the address.

    func:
        lds  r24,var.1505
        subi r24,lo8(-(1))
        sts  var.1505,r24
        ret
        .local  var.1505
        .comm   var.1505,1,1
    

    Automatic

    Automatic variables are held in registers if possible, otherwise the compiler allocates space in the frame of the function. It may even be the case that variables are optimized out, and in that case they do not exist anywhere in the program:

    int add (void)
    {
        int a = 1;
        int b = 2;
        return a + b;
    }
    

    add:
        ldi r24,lo8(3)
        ldi r25,0
        ret
    

    There are 3 types of entities that are stored in the frame of a function, all of which might be present or absent depending on the program:

    For a description on how exactly the frame is being layed out and arguments are being passed, see [Frame Layout and Argument Passing] (https://gcc.gnu.org/wiki/avr-gcc#Frame_Layout).

    1 Some AVRs actually allow this, but you never (like in NEVER) want to pass around the address of a general purpose register!