Tom Kelliher, CS 220
Dec. 3, 1997
Get started coding and testing so you can ask questions early and often.
######################################################################
# factorial --- compute factorial of $a0 and return result through
# $v0
######################################################################
.text
factorial:
sub $sp, $sp, 16
sw $fp, 16($sp)
sw $ra, 12($sp)
sw $s0, 8($sp)
add $fp, $sp, 16
sw $a0, -12($fp) # Our value n.
move $s0, $a0
bgt $s0, 1, recurse # Base case. Return 1
li $v0, 1
lw $s0, 8($sp)
lw $ra, 12($sp)
lw $fp, 16($sp)
add $sp, $sp, 16
jr $ra
recurse: sub $a0, $a0, 1 # Recursive call. Compute (n-1)!
jal factorial
mul $v0, $v0, $s0 # n * (n-1)!
lw $s0, 8($sp)
lw $ra, 12($sp)
lw $fp, 16($sp)
add $sp, $sp, 16
jr $ra
See postfix.cc. With the exception of main, these routines are hand-compiled from the C++ source.
######################################################################
# postfix.hints - small example program containing some of the
# postfix.cc routines. Reads a line of input from the keyboard.
# If the line's prefix is a positive integer, the value is printed.
######################################################################
.data
nl: .asciiz "\n"
full: .asciiz "Trying to push onto a full stack."
empty: .asciiz "Trying to pop from an empty stack."
prompt: .asciiz "? "
.align 2 # Make sure the stack is on
# a word boundary.
stack: .space 512
line: .space 80
######################################################################
# main
######################################################################
.text
.globl main
main:
# This is just an example. You will need a larger
# frame for main.
sub $sp, $sp, 8
sw $fp, 8($sp)
sw $ra, 4($sp)
add $fp, $sp, 8
# Initialize globals.
la $t8, stack
addi $t8, $t8, 512 # $t8 is top of stack. Points
# to tos element. Stack grows
# down in memory. Its size is
# 128 words.
la $t9, line # $t9 is the line pointer.
# Points to next character to
# be examined.
# Example code. Reads a value from the keyboard and
# displays it.
li $v0, 4 # Print a prompt.
la $a0, prompt
syscall
li $v0, 8 # Read a line of input
la $a0, line
li $a1, 80
syscall
jal getValue # Call getValue.
move $a0, $v0 # Move return value from
# getValue
li $v0, 1 # Print the value.
syscall
li $v0, 4 # Print a newline.
la $a0, nl
syscall
la $a0, full # Example of using die, which
# takes a char pointer as a
# parameter.
jal die
lw $ra, 4($sp)
lw $fp, 8($sp)
add $sp, $sp, 8
jr $ra
######################################################################
# isdigit - decimal-digit character test. The argument should be in
# $a0. The test value will be returned through $v0. Returns 1
# if the argument is one of ASCII 0 through 9; otherwise returns 0.
######################################################################
.text
.globl isdigit
isdigit:
sub $sp, $sp, 8
sw $fp, 8($sp)
sw $ra, 4($sp)
add $fp, $sp, 8
li $v0, 0
blt $a0, '0', isdigit_eif1
bgt $a0, '9', isdigit_eif1
li $v0, 1
isdigit_eif1:
lw $ra, 4($sp)
lw $fp, 8($sp)
add $sp, $sp, 8
jr $ra
######################################################################
# exit - Terminate program execution.
######################################################################
.text
.globl exit
exit:
li $v0, 10
syscall
######################################################################
# die - Print the error message pointed to by the char pointer in $a0
# and terminate.
######################################################################
.text
.globl die
die:
sub $sp, $sp, 8
sw $fp, 8($sp)
sw $ra, 4($sp)
add $fp, $sp, 8
li $v0, 4
syscall
li $v0, 4
la $a0, nl
syscall
jal exit
# Not reached.
lw $ra, 4($sp)
lw $fp, 8($sp)
add $sp, $sp, 8
jr $ra
######################################################################
# getValue - Read a postive integer. The first digit is pointed to
# by $t9, which is advanced as each digit is consumed. The value
# read is returned through $v0.
######################################################################
.text
.globl getValue
getValue:
sub $sp, $sp, 20
sw $fp, 20($sp)
sw $ra, 16($sp)
sw $s0, 12($sp)
sw $s1, 8($sp)
# 4($sp) is being held for local variable value.
add $fp, $sp, 20
li $s0, 0 # $s0 holds value.
getValue_w1:
lb $s1, 0($t9) # $s1 holds current character.
move $a0, $s1 # Test the character.
jal isdigit
beqz $v0, getValue_ew1
mul $s0, $s0, 10 # Update value.
add $s0, $s0, $s1
sub $s0, $s0, '0'
add $t9, $t9, 1 # Increment line pointer.
b getValue_w1
getValue_ew1:
move $v0, $s0 # Set-up return value.
lw $s1, 8($sp)
lw $s0, 12($sp)
lw $ra, 16($sp)
lw $fp, 20($sp)
add $sp, $sp, 20
jr $ra