As the previous section has shown, the
$pc register controls the next statement to be executed in a program. When calling a subprogram the
$pc is set to the first line in the subprogram, so to return from the subprogram it is simply a matter of putting into the
$pc the address of the instruction to execute when returning from the subprogram. To find this return address, the mechanics of a subprogram call must be defined.
No matter what HLL the reader has used, the semantics of a subprogram call is always the same. When the call is executed the program transfers control to the subprogram. When the subprogram is finished, control is transferred back to the next statement immediately following the subprogram call in the calling subprogram. This is illustrated in Figure5.5 below.
What this says it that when the subprogram is called the next sequential address of an instruction must be stored, and when the subprogram is complete the control must branch back to that instruction. In the example in the last section, Figure 5.3 showed the subprogram call was at instruction 0x0040001c, and the next sequential instruction would have been 0x00400020. So the value 0x00400020 must be stored somewhere and when the end of the subroutine is reached the program must transfer control back to that statement.
Figure 5.6 is a screen shot when the program is executing at the first line in the PrintNewLine subroutine. This is the same as Figure 5.4, but now the register circled is the
$ra register. Note that in the
$ra register is stored the address 0x00400020. This tells us that the jal operator not only sets the
$pc register to the value of the label representing the first line of the subprogram, it also sets the
$ra register to point back to the next sequential line, which is the return address used after the subprogram completes.
Now the entire life-cycle of calling and returning from a subprogram can be explained. When a subprogram is called, the
jal operator updates the
$pc register to point to the address of the label for the subprogram. The
jal operator also sets the
$ra register to the next sequential address after the subprogram call. When the "
jr $ra" instruction is called, the subprogram returns by transferring control to the address in the
This also explains why a subprogram in this chapter cannot call another subprogram. When the first subprogram is called, the value for the return is saved in the
$ra. When the second subprogram is subsequently called, the value in the
$ra is changed, and the original value is lost. This problem will be explored more in the exercises at the end of the chapter.