Introduction to SPIM

Tom Kelliher, CS 220

Nov. 24, 1997

Announcements

If all goes well, I'll return your second midterm today.

Assignment

  1. Re-read Sections 2, 3, and 4 of the SPIM paper.

  2. Non-destructively determine if I prefer mincemeat pie to pumpkin pie. :-)

Introduction to SPIM

Let's look at a program which reads and writes strings:

# echo.spim --- Read and echo a line from the console.  Demonstrates
#    syscalls for reading and writing strings.

            .data
line:       .space 80
prompt:     .asciiz "Enter a line to be echoed.\n"
nl:         .asciiz "\n"

            .text
            .globl main
main:       li $v0, 4         # Syscall code for print string.
            la $a0, prompt    # Starting address of string.
            syscall

            li $v0, 8         # Syscall code for read string.
            la $a0, line      # Starting address of buffer.
            li $a1, 80        # Length of buffer.
            syscall

            li $v0, 4
            la $a0, nl
            syscall

            li $v0, 4
            la $a0, line
            syscall

            li $v0, 10        # Syscall code for exit.
            syscall

Note:

  1. .space must be used to declare arrays. Unit of allocation is a byte.

  2. Execution begins with main, which must be .globl'ed. Breakpoints must be declared .globl.

  3. li instruction is used to load an immediate into a register. ALU instructions ( add, etc.) may only reference registers.

  4. I/O is accomplished via syscall:
    1. How does it know to read/write integer/string or exit? Each operations has an integer code, loaded into $v0. (See Table 1 on pg. 8 of SPIM paper.)

    2. Use of $a0 and $a1 for parameter passing.

    3. Values returned through $v0.

A program which sums n integers:

# addn.spim
# Input: A number of inputs, n, and n integers.
# Output: The sum of the n inputs.
# Demonstrates reading and writing integers.

# Register usage:
#    $t0: how many integers remain to be read.
#    $t1: sum of the integers read so far.

            .data                         # Constants.
prmpt1:     .asciiz "How many inputs? "
prmpt2:     .asciiz "Next input: "
sum:        .asciiz "The sum is "
nl:         .asciiz "\n"

            .text                   # Main.
            .globl main

main:       li $v0, 4               # Syscall to print prompt string.
            la $a0, prmpt1
            syscall

            li $v0, 5               # Syscall to read an integer.
            syscall                 # Result returned in $v0.
            move $t0, $v0           # n stored in $t0.

            li $t1, 0               # sum stored in $t1 -- clear it.

            .globl while
while:      blez $t0, endwhile      # Read n integers.
            li $v0, 4               # Prompt for next integer
            la $a0, prmpt2
            syscall

            li $v0, 5               # Read next integer.
            syscall
            add $t1, $t1, $v0       # Increase sum by new input.

            sub $t0, $t0, 1         # Decrement n.

            b while

endwhile:   li $v0, 4               # Print result string.
            la $a0, sum
            syscall

            move $a0, $t1           # Print sum.
            li $v0, 1
            syscall

            li $v0, 4               # Print a newline character.
            la $a0, nl
            syscall

            li $v0, 10              # Syscall to exit.
            syscall

Note:

  1. Observe how the value returned from the read integer syscall copied to a register for later use.

  2. The use of $t0 and $t1.

  3. while is made global so that it can serve as a breakpoint.



Thomas P. Kelliher
Thu Nov 20 13:40:33 EST 1997
Tom Kelliher