# Compute the maximum of an array of numbers # Assumes there is at least one element in the array # # Mark A. Sheldon # Olin College # Fall 2010 ########################################################################### ## max ## computes the maximum of an array of integers ## ## Register index ## s0 address of each element of array as we go through the loop ## s1 loop control variable: starts at size of array and counts down ## s2 keeps the current maximum element ## s3 holds each element of array to be compared against current max ## s4 holds result of comparison: 1 if we have a new max ########################################################################### .text .globl main max: subiu $sp, $sp, 32 # Allocate stack frame sw $ra, 28($sp) # Save return address sw $fp, 24($sp) # Save frame pointer sw $s0, 20($sp) # Save callee-saves registers sw $s1, 16($sp) sw $s2, 12($sp) sw $s3, 8($sp) addu $fp, $sp, 32 # Point to base of frame move $s0, $a0 # Pull out address of array move $s1, $a1 # and size # Print the input array # $a0, $a1 still contain array pointer and size la $a2, arrlbl # third argument for print: message address # if we had any caller-saves registers in use, # we'd save them here jal print_arr # call print routine. # we would restore caller-saves registers here lw $s2, 0($s0) # Load first elem of array as initial max max_loop: addi $s0, $s0, 4 # point to next array element addi $s1, $s1, -1 # decrement loop counter: loop (size - 1) times blez $s1, max_loop_done lw $s3, 0($s0) # Get next value from array slt $s4, $s2, $s3 # if current max is NOT less than this element beqz $s4, max_loop # continue loop move $s2, $s3 # else j max_loop # this element is current max max_loop_done: la $a0, anslbl # Print answer label li $v0, 4 syscall move $a0, $s2 # Move max into arg for printing li $v0, 1 # Print integer service syscall la $a0, nl li $v0, 4 # Print string syscall move $v0, $s2 # Return max in $v0 lw $ra, 28($sp) # Restore return address lw $fp, 24($sp) # Restore frame pointer lw $s0, 20($sp) # Restore callee-saves registers lw $s1, 16($sp) lw $s2, 12($sp) lw $s3, 8($sp) addiu $sp, $sp, 32 # Deallocate stack frame jr $ra .data space: .asciiz " " # space to insert between numbers arrlbl: .asciiz "\nThe input numbers are:\n" anslbl: .asciiz "\nThe max is: " nl: .asciiz "\n" ########################################################################### ## print_arr ## Print an array of numbers on one line. ## It doesn't use (and thus doesn't save) any callee-saves registers ## Because it is a leaf procedure, it doesn't save $ra either ## ## $a0: Address of first element of array ## $a1: Number of elements in array ## $a2: Address of message to print first or 0 if no message ########################################################################### .text print_arr: move $t0, $a0 # starting address of array move $t1, $a1 # initialize loop counter to array size # Print header beqz $a2, print_loop # Skip printing header if no header specified move $a0, $a2 # load address of print heading li $v0, 4 # specify Print String service syscall # print heading # Print elements of array print_loop: # print element lw $a0, 0($t0) # load array element for printing li $v0, 1 # specify Print Integer service syscall # print array element # print space la $a0, space # load address of space for syscall li $v0, 4 # specify Print String service syscall # output space # update loop control variables addi $t0, $t0, 4 # increment address addi $t1, $t1, -1 # decrement loop counter bgtz $t1, print_loop # repeat if not finished # print newline la $a0, nl li $v0, 4 syscall jr $ra # return .data ########################################################################### ## main ########################################################################### size: .word 5 arr: .word 1, 2, -3, 14, 0 #size: .word 1 #arr: .word -99 .text main: la $a0, arr # load address of array la $a1, size # load address of size variable lw $a1, 0($a1) # load array size jal max move $a0, $v0 li $v0, 1 # print the answer again syscall la $a0, nl # and a newline li $v0, 4 syscall li $v0, 10 # system call for exit syscall # we are out of here.