Electronic – AVR local and global variable program size

avrmemory

I work on ATmega8 and I need to optimize my code as well as I can, because I am over limit and I saw something surprising. I have a few 8bit integers declared as global variables and a few 8bit integer declered as local variables. And in some case when I change global variable to local I get extra bytes of program and in same cases when I change local variable to global I also get extra bytes. Can anyone explain me why in same cases global variables generate smaller size of program and sometimes local variables do that?

Best Answer

Global variables are placed in the .data section of your program (if explicitly initialized) or in the .bss section (if not initialized). The initial values for global variables are copied over from flash upon start up by the __do_copy_data() function (added by the linker scripts if needed) and the initialization of the variables in .bss to zero (this is mandated by the C standard) is done by __do_clear_bss(). Your program includes symbols which tell it the size of these two segments. Code must be included to handle these events. Note that sometimes these variables can be bound to a register.

Local variables on the other hand reside either in registers or the stack. Being a modified Harvard Machine, AVR has a large number of registers, thus, if local variables can be put there, they will, as to avoid memory access. This means that for local variables, if residing in the stack, there must be code to

  1. Increase the stack frame for your function.
  2. Initialize the values of these variables.
  3. Perform a load/modify/store cycle every time they change (this also needs to be done for globals).

As a result, depending on the amount of code that needs to be added to the binary will change. For further details, you can see what is actually happening by disassembling your binary (avr-objdump is a good starting place) and by listing the symbols in the file (avr-nm).

Cheers.