The next subprogram to be implemented will print a new line character. This subprogram will allow the program to stop inserting the control character "\n" into their programs. It will be used here to illustrate how to return from a subprogram.
Program 5-2: Implementing and calling the PrintNewLine subprogram # File: Program5-2.asm # Author: Charles Kann # Purpose: To illustrate implementing and calling a subprogram named PrintNewLine. .text main: # read an input value from the user li $v0, 4 la $a0, prompt syscall li $v0, 5 syscall move $s0, $v0 # print the value back to the user jal PrintNewLine li $v0, 4 la $a0, result syscall li $v0, 1 move $a0, $s0 syscall # call the Exit subprogram to exit jal Exit .data prompt: .asciiz "Please enter an integer: " result: .asciiz "You entered: " # subprogram: PrintNewLine # author: Charles Kann # purpose: to output a new line to the user console # input: None # output: None # side effects: A new line character is printed to the user's console .text PrintNewLine: li $v0, 4 la $a0, __PNL_newline syscall jr $ra .data __PNL_newline: .asciiz "\n" # subprogram: Exit # author: Charles Kann # purpose: to use syscall service 10 to exit a program # input: None # output: None # side effects: The program is exited .text Exit: li $v0, 10 syscall
5.2. 1 Commentary on Exit subprogram
- This program now has three
.textsegments, but the reason for this is becomes obvious when the code is examined. The
PrintNewLinesubprogram requires a value to be stored in the
.datasegment, the newline character. The
.textsegments are needed to inform the assembler that program instructions are again contained in the code. This is emphasized here as it points out a good rule to follow when writing subprograms. Always begin the subprogram with a
.textstatement. If the assembler already thinks it is in a
.textsegment, there is no effect, but the subprogram is protected from the case where the assembler thinks it is assembling a
.datasegment when reaching the subprogram. In real life files can change often, and omitting a simple
.datasegment when it should be present can lead to myriads of unnecessary problems.
- The PrintNewLine subprogram shows how to return from a subprogram using the instruction "
jr $ra". The next section of this chapter will explain how this actually works. For now, this can be thought of as a return statement.
- A label was needed in the PrintNewLine subprogram to contain the address of the newline variable. In MIPS assembly, you cannot use labels with the same name15. This subprogram will eventually become part of a utility package which will be used by a number of programs. Care must be taken to make sure that any label used will conflict with a label in a program. So the convention of putting a double underscore (__) before the variable, a string representing the subprogram it is in (PNL), and another underscore before the variable name (newline) is used. It is hoped that this will solve nearly all name conflicts.
$v0registers have been changed, but this is not listed as a side effect of the program. Part of the definition of the registers says that the save registers (
$s0..$s9) must contain the same value when the subprogram returns as they did when the subprogram was called. For these simple subprogram, that means that these registers cannot be used. All other registers have no guarantee of the value after the subprogram is called. A programmer cannot rely on the values of
$v0once a program is called. So while changing them is a side effect of calling the function, it does not have to be listed as it is implied in the execution of the method.
15 More accurately, in MIPS you cannot use labels with the same name unless the labels are resolved to addresses so that they do not conflict. If separate assembly and linking are performed, any none global symbols can be used in any file, so long as it is in that file once. This text does not handle separate compilation and linking, so the rule that label names cannot be repeated is correct for all programs in this text.