System Calls

Directly interfacing hardware to do input and output is complex. The programmer must be aware of hardware state and addresses and will need to write routines to do simple things that divert time from solving the problem at hand. For these and other reasons, computers come with BIOS and OS routines that take care of these tasks.

SPIM provides 10 simple functions that you will need to master to write effective programs.


Using System Calls to Display A Message: An Example

System calls are easy to use once you understand them. The function you want the call to perform is specified in $v0. Parameters sent to the function are placed in predefined registers. Output is placed in other predefined registers or in memory at locations specified in the parameter list.

A simple and useful first system call is Print String. It is call #4. It takes the address of a NUL terminated string as its argument. The three lines following main: in the next example do all the work.

        .data
msg1:   .asciiz "Hello! My name is Jim Bob.\n"
        .globl __start
        .text

__start:
        li      $v0, 4          #System call for Print String
        la      $a0, msg1       #Load address of message into $a0
        syscall

        li      $v0, 10         #Correctly end program
        syscall
If there were no system call for printing to the screen the above example might look like this:
        .data

msg1:     .asciiz "Hello! My name is Jim Bob.\n"
outstate: .word 0xffff0008
outport:  .word 0xffff000c

        .globl 	__start
        .text

__start:	
#And now the hard way:

#some set up
        la      $t1, msg1
        li      $t2, 0x00000001	#Bit mask for terminal output ready bit

#for ($t4 = 0; $t4 < 27; t+=1) {
        move    $t4, $0         #initialize for loop counter
prnlp:                          #for loop start point

        #do {
        waitlp:
                lw      $t5, outstate
                lw      $t3, ($t5)      #Load terminal output status
                and     $t3, $t3, $t2   #Mask ready bit
                beqz    $t3, waitlp     #continue waiting if not ready
        #} while ( terminal not ready );

        lbu     $t3, msg1($t4)  #get current character

        lw      $t5, outport
        sw      $t3, ($t5)      #send current character to output
                                #Only low 8 bits are significant.

        addi    $t4, $t4, 1	#for loop counter increment.
        blt     $t4, 27, prnlp  #for loop condition
#} //for


        li      $v0, 10		#Correctly end program
        syscall

System Calls

Here's a quick summary of the system calls, or syscalls, available to you in SPIM. These system calls simulate services normally provided by the operating system. A similar set of functions is available to assembly programmers in most environments, though there are usually more and they may be more complex.

Function
Code
($v0)

Function

Other Important Registers

Sample Code

1

Print an Integer

INPUT
$a0 : the integer to be printed
        li $a0, 12345
        li $v0, 1
        syscall

2

Print a Float

INPUT
$f12 : the Floating point number to be printed.
        .data
fvar:   .float 1.125
        .text        
        l.s $f12, fvar
        li $v0, 2
        syscall

3

Print a Double

INPUT
$f12 : the Double to be printed.
        .data
dvar:   .double 1.2345678901234567
        .text        
        l.d $f12, dvar
        li $v0, 3
        syscall

4

Print a String

INPUT
$a0 : the address of the string to be printed.
        .data
str1:   .asciiz "I'm a string!"
        .text
        la $a0, str1
        li $v0, 4
        syscall

5

Read an Integer

OUTPUT
$v0 : the integer that was read
        li $v0, 5
        syscall

6

Read a Float

OUTPUT
$f0 : the Floating point number that was read
        li $v0, 6
        syscall

7

Read a double

OUTPUT
$f0 : the double that was read
        li $v0, 7
        syscall

8

Read a String

INPUT
$a0 : Address of input buffer in memory
$a1 : size of buffer (n bytes)

OUTPUT
Input buffer has user's input loaded into it.
It contains up to n-1 characters and is NUL terminated.
        .data
str2:   .space 255
        .text        
        la $a0, str2
        li $a1, 255
        li $v0, 8
        syscall
        li $v0, 4
	syscall

9

Dynamically allocate
n bytes of memory.

INPUT
$a0 = n The number of bytes to allocate.

OUTPUT
$v0 : A pointer to the bytes allocated.
        li $a0, 255
        li $v0, 9
        syscall #Get memory

        move $a0, $v0
        li $a1, 255
        li $v0, 8
        syscall #Read String
        li $v0, 4
        syscall #Display String

10

Exit.

 
        li $v0, 10 
        syscall

Special Characters Worth Noting

Character Escape
Newline \n
Tab \t
Double Quote \"

Try It Out!

The sample code can be cut and pasted into an empty project. You could use the sample at the top of the page. Not all the samples send output to the console. For those you can use PCSPIM's register window to show you the effect of the operation.

Notes on the sample code for each system call function
  1. –  4. These can be cut and pasted directly into an empty program framework. Notice that you can switch back and forth between the data and text segments if you need to. This has been done only to simplify the example code. It is not a recommended practice. Plan your code ahead of time and put your variables in a place that is easy to find.
  2. There's no prompt. Just type an integer value and hit enter. Observe the change to $v0 in the register window.
  3. Again no prompt. Type in a floating point number, such as 1.234 and hit enter. Scroll down in the register window to observe the Single Floating Point Register Display for FP0 — also known as $f0
  4. Still no prompt. Type in a floating point number, such as 1.010101010101, and hit enter. Scroll down in the register window to observe the Double Floating Point Register Display for FP0 — also known as $f0. What's wrong with the Single Floating Point Register Display for FP0?
    Notice that 64bit doubles take up two 32bit FP registers so there are only have as many and they only have even numbers.
  5. Type in a string. It will be echoed back to you in the console.
  6. This one is just like the other, except the memory is dynamically allocated. As you step through the program observe the value of the pointer to allocated memory in $v0. If there is no memory to allocate what value do you suppose the pointer will have?
  7. Hopefully you have used the last one already!

This page last modified by Alex Clarke:
Tuesday, 12-Dec-2006 14:53:33 CST

CS Dept Home Page
CS Dept Class Files

Copyright: Department of Computer Science, University of Regina.