Stack arguments and a stack frame

Two arguments pushed by the caller, a local that survives a call inside a link frame, and a subroutine that gives back the register it borrowed.

sum_of_squares(a, b) takes its two arguments on the stack, calls a second subroutine twice to square them, and returns their sum in d0. It needs a local variable to hold the first square while the second call runs, and that local lives on the stack too, in a frame link builds for it.

A subroutine with its arguments in registers passed everything in d0 and d1. That works until a subroutine has to keep something across a call, because the call is free to destroy any register it likes.

You need to know: the "bsr, rts, link and unlk" lecture and the "The stack, -(sp) and movem" lecture. What is new here is a6 as a frame pointer, it stays still in the middle of the frame while sp keeps moving, so 8(a6) names the same argument from the first instruction to the last.

link a6, #-4 pushes a6, copies sp into it and then takes four more bytes of stack. Once it has run, the frame is this, with 🟢 on the stack pointer:

addressvaluereached aswhat it is
$FFFFEC🟢 00000009-4(a6)the local, a * a
$FFFFF000000000(a6)the caller's a6, and where a6 now points
$FFFFF40000100C4(a6)the return address
$FFFFF8000000038(a6)a
$FFFFFC0000000412(a6)b

The arguments are above a6 because the caller pushed them before the bsr, and the locals are below it in the room the #-4 reserved. Type FFFFE0 in the memory panel after running and the five longs are still lying there, since popping moves a pointer and erases nothing.

square keeps to a smaller agreement of its own: it uses d1 and puts it back, so a caller in the middle of a computation does not lose what it was holding. unlk a6 puts sp back to the return address and pops the old a6, and the add.l #8, sp in the caller is the eight bytes of arguments being given back. d0 and d7 come out at 00000019, which is 25, from 9 plus 16.

Try changing add.l #8, sp to add.l #4, sp. The answer is still right, and a7 ends at 00FFFFFC instead of 01000000: four bytes of stack the program will never get back, which in a loop is how a program runs out of it.