Recursive compiled code makes every call and return transfer explicit.
Inspect and execute a factorial controller with one entry label, one base-case label, saved continuations, and an indirect return through continue.
Guiding question
What machine state replaces the implicit call stack of a recursive source procedure?
Read the full assembled instruction list for one recursive procedure
Identify entry, after-call, base-case, and done labels
Save the caller continuation and live argument before a recursive call
Restore state before multiplying the returned value
Return indirectly through the continue register
Measure entries, instructions, maximum stack depth, and final stack balance
The compiled listing begins at factorial-entry. Every non-base call saves continue and n, decrements n, installs after-factorial as the new return address, and jumps back to the same entry. The base case places 1 in val and returns through continue. after-factorial restores the caller state, multiplies n by the returned val, and returns again.
The instrumented run starts with n = 5 and continue pointing to done. Six entries are observed, including n = 0. Five suspended calls each hold two stack values, so maximum stack depth is 10. All ten values are restored before halt. The 66 fetched instructions and exact controller listing measure this finite compiled procedure.
The listing returns (((factorial-entry . 0) (after-factorial . 8) (base-case . 12) (done . 14)) 15 (perform test branch save save assign assign goto restore restore assign goto assign goto halt)). The run returns (15 complete 120 66 10 #t (5 4 3 2 1 0)).
Trace focus
Follow continue changing from done to after-factorial before each recursive jump. At the base case, trace five indirect returns through the same after-call code. Match each pair of save instructions with the later restores and verify that stack depth returns from 10 to 0 before the final goto reaches done.
Try it yourself
Change the program and compare the result.
Translate a recursive Fibonacci or exponentiation procedure into the same explicit listing. State which registers remain live across each recursive call and predict the maximum stack depth for one representative input.
Show hint
Save exactly the continuation and values needed after the recursive result returns. A procedure with two recursive calls must also preserve the first returned value while computing the second.