You are on page 1of 3

# PURPOSE: To read non-negative reals and evaluate cos(x)

# at the point just read.


# INPUT: A file of positive reals terminated by a negative real.
# OUTPUT: cos(x) for each non-negative x read from input.
.data
.align 2
prompt1: .asciiz "\n\nThis program evaluates cos(x) for x >= 0."
prompt2: .asciiz "\nEnter a non-negative real number (< zero to quit). "
answer: .asciiz " is the cos of "
newline: .asciiz "\n"
zero: .float 0.0
one: .float 1.0
comp: .float 0.00001
negone: .float -1.0
.text
.globl main
main:
# print the prompt messages
li $v0, 4 # $v0 = print_string system call code
la $a0, prompt1 # $a0 = address of first prompt
syscall # print first prompt
l.s $f20, zero # $f20 = 0.0
# Read numbers and find cos(x)
read: li $v0, 4 # $v0 = print_string system call code
la $a0, prompt2 # $a0 = address of second prompt
syscall # print second prompt
li $v0, 6 # $v0 = read_float system call code
syscall # read a float - x
c.lt.s $f0, $f20 # set cond. flag if x < 0.0
bc1t quit # end program if number <= 0.0
mov.s $f12, $f0 # put input number into function argument
mov.s $f14, $f12 # put input number into $f13 for printing later
jal cos # call function to evaluate cos(x)
mov.s $f12, $f0 # put cos(x) into $f12 for printing
li $v0, 2 # $v0 = print_float system call code
syscall # print cos(x)
li $v0, 4 # $v0 = print_string system call code
la $a0, answer # $a0 = address of answer
syscall # print part of answer
mov.s $f12, $f14 # put x into $f12 for printing
li $v0, 2 # $v0 = print_float system call code
syscall # print x
j read # go back and read another target
# Call system exit
quit:
li $v0, 4 # $v0 = print_string system call code
la $a0, newline # $a0 = address of answer
syscall
li $v0, 10 # $v0 = exit system call code
syscall # halt program execution
# Algorithm for computing cos - in pseudocode
# k = 0, den = 1
# sum = 1, num = 1
# x2 = x*x
# loop
# num = (-1)*num*x2
# den = den*(k+1)*(k+2)
# term = num/den
# sum = sum + term
# exit loop if |term| < 0.00001
# k = k + 2
# end loop
# return sum
# Register usage
# $f12 = function argument, x
# $f0 = return value, cos(x)
# $f4 = initial k, 0.0
# $f5 = initial den, 1.0
# $f6 = initial sum, 1.0
# $f7 = initial num, 1.0
# $f8 = initial term, 0.0
# $f9 = comparison for term, 0.00001
# $f10 = -1.0
# $f11 = 1.0
# $f0 - $f3 return values from function calls
# $f4 - $f11 temporary values
# $f12 - $f15 arguments passed to functions
# $f16 - $f19 more temporary values
# $f20 - $f31 saved registers

cos:
# loading initial number
s and operation numbers
l.s $f4, zero # load float 0.0 into $f4, k
l.s $f5, one # load float 1.0 into $f5, den
l.s $f6, one # load float 1.0 into $f6, sum
l.s $f7, one # load float 1.0 into $f7, num
l.s $f8, zero # load float 1.0 into $f8, term
l.s $f9, comp # load float 0.00001 into $f9, compariso
n
l.s $f10, negone # load float -1.0 into $f10
l.s $f11, one # load float 1.0 into $f11
mul.s $f13, $f12, $f12 # x2 = x*x
loop:
# the math
mul.s $f7, $f7, $f10 # num*(-1) = num
mul.s $f7, $f7, $f13 # (-1)*num*x2
add.s $f4, $f4, $f11 # k = k + 1
mul.s $f5, $f5, $f4 # den = den*(k+1)
add.s $f4, $f4, $f11 # k = k + 2
mul.s $f5, $f5, $f4 # den = den*(k+1)*(k+2)
div.s $f8, $f7, $f5 # term = num / den
add.s $f6, $f6, $f8 # sum = sum + term
mov.s $f16, $f8 # copy term into $f16
# absolute value of term
l.s $f17, zero # load 0.0 into $f17
c.lt.s $f17, $f16 # set cond. flag if 0 < term
bc1t positive # positive if number >= 0
sub.s $f16, $f17, $f16 # term = 0 - term
positive:
c.lt.s $f16, $f9 # set cond. flag if x < 0.00001
bc1t exitcos # end program if number <= 0.00001
j loop # jump to loop
exitcos:
mov.s $f0, $f6 # copy sum into $f0
jr $ra # return

You might also like