Ja genau, so in etwa sieht es aus.

Stack wird einfach am Ende von SRAM eingerichtet ( deswegen dieses RAMEND)
und wird benutzt um irgendwas eben kurz zwischenzuspeichern.

Die erste Möglichkeit hast Du schon genannt, bei rcalls speichert der µC die Adresse, wo er anschließend zurückspringen soll auf dem Stack und bei ret holt er sie sich wieder um zu wissen wo jetzt hin.
Das macht er auch bei Interrupts, da landet die Rücksprungadresse auch auf dem Stack.
Eine Eigenschaft vom Stack ist aber, daß ich nur was obendrauf werfen , oder nur was von oben hollen kann. an Sachen die dazwischen liegen komm ich nicht dran, ist wie ein Stapel
Bettonplatten, ich muß immer von oben entnehmen, oder obendrauf legen, kapito?

Jetz kommt eine schöne Sache, wo man den Stack benutzen kann.
bei Eintritt in die Interruptroutine hast Du den SREG in einen Register zwischengespeichert, gut, nur was machst Du wenn Du keinen Register mehr übrig hast?
Dann nimmst Du den Stack!

es geht so:

in tmp,SREG ;kopiere Inhalt von SREG in tmp
push tmp ;lege Inhalt von tmp auf den Stack
............ Hier folgt das Programm
pop tmp ;Hole die Spitze, also die oberste Stelle vom Stack und schreibe es in tmp
out SREG,tmp ; Gerettet!
reti

aber bevor wir einen RIESEN großen Fehler machen nochmal
das Gleiche, nur etwas kommt noch dazu:

push tmp ;lege tmp auf den Stack
in tmp,SREG ;kopiere Inhalt von SREG in tmp
push tmp ;lege Inhalt von tmp auf den Stack
............ Hier folgt das Programm
pop tmp ;Hole die Spitze, also die oberste Stelle vom Stack und schreibe es in tmp
out SREG,tmp ; Gerettet!
pop tmp ;Auch geretet!
reti

Kannst Du sagen, wo der unterschied ist, und was passiert wenn man den erste Code nimmt?