Andrew Appel states that return addresses were earlier pushed on the stack by the function call instruction. Data shows that it is faster and easier to pass the return addresses in a register. This has two advantages
- It keeps the memory traffic down
- It avoids building in any particular stack discipline into the machine
This is certainly true for MIPS, ARM, etc. For the Intel IA32 platform see Notes on Translating Three-Address Code to Assembly Code for the X86.
The return address is still stored on stack. Generally the ENTER, LEAVE and RET instructions are used for stack manipulation. Gcc uses CALL, LEAVE and RET.