O AVR (a família de microcontroladores tradicionalmente usada em placas Arduino) é uma arquitetura de Harvard , o que significa que código e variáveis executáveis estão em duas memórias separadas - neste caso, flash e SRAM. O código executável nunca sai da memória flash.
Quando você chama uma função, o endereço de retorno geralmente é enviado para a pilha - a exceção ocorre quando a chamada da função ocorre no final da função de chamada. Nesse caso, o endereço de retorno da função que chamou a função de chamada será usado - ele já está na pilha.
Se quaisquer outros dados são colocados na pilha depende da pressão do registro na função de chamada e na função chamada. Registradores são a área de trabalho da CPU, o AVR possui 32 registros de 1 byte. Os registradores podem ser acessados diretamente pelas instruções da CPU, enquanto os dados na SRAM primeiro precisam ser armazenados nos registradores. Somente se os argumentos ou a variável local forem muito grandes ou muitos para caberem nos registros, eles serão colocados na pilha. No entanto, as estruturas são sempre armazenadas na pilha.
Você pode ler os detalhes de como a pilha é usada pelo compilador GCC na plataforma AVR aqui: https://gcc.gnu.org/wiki/avr-gcc#Frame_Layout
Leia as seções "Layout do quadro" e "Convenção de chamada" .