SPIM provides a small set of operating-system-like services through the system call (syscall) instruction. To request a service, a program loads the system call code (see Table 1) into register $v0 and the arguments into registers $a0...$a3 (or $f12 for floating point values). System calls that return values put their result in register $v0 (or $f0 for floating point results). For example, to print ``the answer = 5'', use the commands:
.data str: .asciiz "the answer = " .text li $v0, 4 # system call code for print_str la $a0, str # address of string to print syscall # print the string li $v0, 1 # system call code for print_int li $a0, 5 # integer to print syscall # print it
print_int is passed an integer and prints it on the console. print_float prints a single floating point number. print_double prints a double precision number. print_string is passed a pointer to a null-terminated string, which it writes to the console.
read_int, read_float, and read_double read an entire line of input up to and including the newline. Characters following the number are ignored. read_string has the same semantics as the Unix library routine fgets. It reads up to n-1 characters into a buffer and terminates the string with a null byte. If there are fewer characters on the current line, it reads through the newline and again null-terminates the string. Warning: programs that use these syscalls to read from the terminal should not use memory-mapped IO (see Section 5).
sbrk returns a pointer to a block of memory containing n additional bytes. exit stops a program from running.
The printf syscall uses a descriptor. The first word of the descriptor is the number of argument words (not counting the address of the format string). Note that doubles count as two words! The second word contains the address of a format string of the usual C printf variety. Arguments follow in succeeding words, with integers, longs, and characters taking one word, doubles taking two words (not necessarily aligned on a double word boundary), and character strings taking one word for the address of the string. The descriptor for the scanf syscall is similar, except the arguments are always addresses, and only floats are read, not doubles. To print ``x = 5 and y = 10.0'', using printf you may use the following commands:
.data fstr: .asciiz "x = %d and y = %4.1f\n" desc: .word 3 .word fstr .word 5 .align 0 .double 10.0 .text li $v0, 11 # system call code for printf la $a0, desc # address of the descriptor syscall # print it