From Computer History Wiki
Revision as of 15:43, 12 May 2023 by Jnc (talk | contribs) (+links)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

A subroutine (or function or procedure) is a block of code (either in the source code, or in the object code) to which control can be transferred so that the code block can perform some desired common operation; when it is done doing so, control returns to the 'caller' of the subroutine.


In the very earliest days of computing, a subroutine was simply a written-out sequence of instructions to perform some common operation (e.g. multiply, on machines which did not have a 'multiply' instruction). The programmer wishing to use that subroutine had to insert a copy of those instructions in their program, at the point at which it was desired to perform that operation.

If the same operation needed to be performed at several different places in the program, thereby necessitating several copies of the code sequence, this was obviously inefficient of space in main memory, particularly crucial in early machines which had very small main memories.

It thus became desirable to allow one copy of the instruction sequence to be shared; to do this, a calling sequence was defined, using existing instructions, where the address to go back to upon completion was stored in a known location, before the subroutine was entered. One copy of the subroutine could thus be 'shared' among multiple uses.

Eventually hardware support (in the form of special instructions) was added to simplify calling sequences, although the first versions were often crude. E.g. in the Whirlwind computer, the subroutine calling sequence used two instructions, 'Sub-Program' and 'Transfer Address': the first saved the current PC value in the accumulator, and then jumped to the subroutine; the second stored the address (in the accumulator) in the address field of an instruction, usually a 'jump' instruction at the end of the subroutine.

(The PDP-10 instruction set contains a 'fossil' from this era: the 'JSA' instruction, which saves the return location in the first word of the subroutine, and then starts execution at the second word.)

Calling sequences were also expanded, to allow arguments to be passed, so that a given subroutine had more flexibility (i.e. one would not need two, slightly different, copies.)

Calling sequences which stored arguments, and the return point, in fixed locations could not be used recursively, so eventually the modern practise, of storing both arguments and the return point on a stack, came into use.