sicp.io
5.1.3 · Subroutines and continuation linkage

One controller segment can return to more than one caller.

A shared machine subroutine receives its return address through a continue register, and saving the old continuation preserves the original caller.

Guiding question

How does a register machine return from shared and nested controller subroutines without duplicating their instructions?

  • Store a caller-specific return address in a continue register
  • Jump into one shared controller segment from two call sites
  • Return through goto-register rather than a fixed label
  • Save an outer continuation before a nested subroutine call
  • Restore the original continuation before returning to the first caller

The first controller calls one double subroutine twice. Before each goto, the caller writes a different pc value into continue. The shared subroutine changes val and executes goto-register continue, so the same two instructions return first to the instruction that saves the left result and later to the instruction that adds the two doubled values. The recorded pc path shows both entries into indices 9 and 10 without copying the routine.

The second controller calls a double-then-add-one subroutine, and that subroutine calls double. The nested call needs continue for its own return address, so the outer subroutine saves the caller’s value first. After double returns, restore recovers the original address, add1 finishes the outer routine, and goto-register returns to main. This finite executor models the lesson’s explicit linkage and one stack slot.

SICP code2,595 of 1,048,576 UTF-8 bytes
Examples
Result
Output
Value
Diagnostic
Execution trace0 / 0 events
    Programs run in the browser with their result and execution trace.
    Expected result

    The shared-subroutine program returns (16 (3 7) (0 1 2 9 10 3 4 5 6 9 10 7 8)). The nested-call program returns (9 1 0 (3 8) (0 1 2 5 6 7 11 12 8 9 10 3 4)).

    Trace focus

    In the first run, locate each assignment to continue, both jumps to the same subroutine pc, and the two goto-register returns to different callers. In the second, follow save before the nested continue assignment, the inner return to pc 8, restore of the original pc 3, and the final return to main. The explicit path and stack depth describe these finite controllers only.

    Try it yourself

    Change the program and compare the result.

    Add a third caller that doubles 7 and includes it in the final sum. Predict its return address and the new pc path before running the machine.

    Show hint

    The shared subroutine still begins at pc 9. The new caller needs its own instruction immediately after the goto and must place that pc in continue.

    Complete this lesson

    0 of 23 lessons complete in this chapter0%