Subroutines are made possible by a mechanism called a subroutine stack. The subroutine stack is a "Last-in First-out" memory. This memory stores program memory addresses. When SPLatty executes a GoSub he notes where he is, and sticks the note on top of the stack, before jumping to the new place in the program. If inside that subroutine there is another Gosub, he again notes where he is, places that note on top of the previous one, and goes to the new place. When he encounters a Return he removes the top note off the stack of notes and goes to the place designated on the note. That way he can "unwind" the places he has to return to perfectly.
The stack of return addresses, the subroutine stack, can only contain a limited number of addresses. For dialects prior to dialect 12 the capacity is 4. From dialect 12 the capacity is 6.
GoTo to get out of a subroutine. This is one of the most common "mystery" mistakes I see people making. If you GoSub you must Return.GoTo into a subroutine. The trap here is that people sometimes accidentally write GoTo when they meant GoSub.Return instruction (that's the one I do). If I have a really confounding bug I search for missing Returns. It is really hard to see something that's not there!YieldTask, WaitOn, Pause and related yielding instructions are not allowed inside such subroutines. SPLat/PC will flag an error and the controller will suffer a fatal runtime error if you violate this rule.