I wanted to save some values to the EEPROM and also wanted to free up SRAM by avoiding some variable declarations, but EEPROM memory is byte wise.

If I want to store an int value, I have to use some expressions repeatedly. I thought I would make some functions for those. But I am concerned that, if I create a function, it would still occupy SRAM memory, better I declare an int variable instead of using EEPROM.

How are the functions and the local variables stored in SRAM? Does it only store the address of the fuction pointer from the flash memory or all the variables and commands are stored on the stack?

  • 4
    Do remember that EEPROM is only writable for a limited number of times, reading it is unlimited. According to the AVR datasheet EEPROM only has 100000 cycles, which sounds as a lot but when you try to use it as SRAM, it will only last a fairly short period.
    – jippie
    Jul 4, 2014 at 22:17
  • OMG! After that, will the EEPROM be useless? I am going to check the datasheet! Jul 5, 2014 at 9:36
  • The Flash memory also has a lifecyle. It's wiser to not burn the program a lot. Jul 5, 2014 at 9:54
  • With normal use the numbers given for flash and EEPROM are no problem at all. The equation changes when you start using it like you use SRAM.
    – jippie
    Jul 5, 2014 at 12:49

5 Answers 5


Only the function's data is stored on the stack; its code stays in flash. You can't really reduce SRAM use by using EEPROM instead because, as you have seen, EEPROM isn't addressable in the same way. The code to read and store EEPROM also needs to use some SRAM - probably as much SRAM as you were trying to save! EEPROM is also slow to write, and has a limited lifetime (in number of writes to each byte), both of which make it impractical to use for storing the kind of temporary data we usually put on the stack. It is better suited to saving infrequently changed data, like the unique device configuration for mass-produced devices, or capturing infrequent errors for later analysis.

Edited: There is no stack for that function until the function has been called, so yes, that is when any of the function's data get's put there. What happens after the function returns is that its stack-frame (its reserved area of SRAM) is no longer reserved. It will eventually be re-used by another function call. Here is a diagram of a C stack in memory. When a stack frame is no longer useful, it is simply released and its memory becomes available to be re-used.

  • I am thinking this way, when the function is called, only then the data inside it is stored in the stack. After execution of the function, the data are erased from stack/SRAM. Am I right? Jul 4, 2014 at 20:29

Local variables and function parameters are stored on the stack. However, that is not a reason not to use them. Computers are designed to work that way.

Stack memory is only in use while a function is active. As soon as the function returns, the memory is freed. Stack memory is a GOOD Thing.

You don't want to use recursive functions with lots of levels of recursion, or allocate lots of large structures on the stack. Normal use is fine however.

The 6502 stack is only 256 bytes, but the Apple II works just fine.

  • So, you mean the function will be saved with all its local variables, parameters and expressions to the stack temporarily, only when it is called? Otherwise it will stay in the program/flash memory? After execution, will it be erased from stack? I was talking about Arduino actually, as it is Arduino Forum, I didn't mention that. Jul 4, 2014 at 20:16
  • No, only the function's parameters and local variables are on the stack. The code of the function is not saved on the stack. Don't over-think this.
    – Duncan C
    Jul 4, 2014 at 20:19

The AVR (the microcontroller family traditionally used on Arduino boards) is a Harvard Architecture, meaning that executable code and variables are in two separate memories - in this case flash and SRAM. The executable code never leaves flash memory.

When you call a function the return address is usually pushed to the stack - the exception is when the function call happens at the end of the calling function. In this case the return address of the function that called the calling function will be used instead - it is already on the stack.
Whether any other data is put on the stack depends on the register pressure in the calling function and in the called function. Registers are the working area of the CPU, the AVR has 32 1-byte registers. The registers can be accessed directly by CPU instructions, whereas data in SRAM will first have to be stored in registers. Only if arguments or local variable are too big or too many to fit in registers will they be put on the stack. However, structures are always stored on the stack.

You can read the details of how the stack is used by the GCC compiler on the AVR platform here: https://gcc.gnu.org/wiki/avr-gcc#Frame_Layout
Read the sections "Frame Layout" and "Calling Convention".


Immediately upon a function call entering the function, the first code that is executed is to decrement the stackpointer by an amount equal to the space required for temporary variables internal to the function. The brilliant thing about this is that all functions therefore become re-entrant and recursive, because their variables are built on the calling program's stack. That means if an interrupt halts execution of one program and transfers execution to another, it too can call the same function without them interfering with eachother.


I've been trying quite hard to make an example bit of code to demonstrate what the excellent answers here are saying, without success so far. The reason is that the compiler aggressively optimizes things. So far my tests have not used the stack at all, even with local variables in a function. The reasons are:

  • The compiler may in-line the function call, thus the return address might not be pushed onto the stack at all. Example:

    void foo (byte a) { digitalWrite (13, a); } void loop () { foo (5); }

    The compiler turns that into:

    void loop () { digitalWrite (13, 5); }

    No function call, no stack used.

  • The compiler may pass arguments in registers, thus saving it having to push them onto the stack. Example:

    digitalWrite (13, 1);

    Compiles into:

    158: 8d e0 ldi r24, 0x0D ; 13 15a: 61 e0 ldi r22, 0x01 ; 1 15c: 0e 94 05 01 call 0x20a ; 0x20a <digitalWrite>

    The arguments are put into registers and thus no stack is used (apart from the return address for calling digitalWrite).

  • Local variables may well be put into registers, again saving having to use RAM. This not only saves RAM but is faster.

  • The compiler optimizes away variables you don't use. Example:

    void foo (byte a) { unsigned long bar [100]; bar [1] = a; digitalWrite (9, bar [1]); } void loop () { foo (3); } // end of loop

    Now that's got to allocate 400 bytes for "bar" doesn't it? Nope:

    00000100 <_Z3fooh>: 100: 68 2f mov r22, r24 102: 89 e0 ldi r24, 0x09 ; 9 104: 0e 94 cd 00 call 0x19a ; 0x19a <digitalWrite> 108: 08 95 ret 0000010a <loop>: 10a: 83 e0 ldi r24, 0x03 ; 3 10c: 0e 94 80 00 call 0x100 ; 0x100 <_Z3fooh> 110: 08 95 ret

    The compiler optimized away the entire array! It can tell that we are really just doing a digitalWrite (9, 3) and that is what it generates.

Moral of the story: Don't try to out-think the compiler.

  • Most non-trivial functions use the stack to save some registers, so that these can be used to hold local variables. Then we have this funny situation where the function's stack frame contains local variables belonging to it's caller. Aug 6, 2015 at 8:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.