i want calculate average value of list on mips. i've tried isolation , works fine if want print out sum or prompt test when put average calculation in, somehow gives me size * 4 answer. assembly code below:
.data size_prompt: .asciiz "enter number of elements: " element_prompt: .asciiz "enter element: " size: .word 0 to_store: .word 0 sum: .word 0 avg: .word 0 .text #prints prompt la $a0, size_prompt addi $v0, $0, 4 syscall #gets input user addi $v0, $0, 5 syscall sw $v0, size addi $t0, $0, 0 #initialise = 0 #creates list lw $s0, size addi $t1, $0, 4 mult $s0, $t1 mflo $t2 add $a0, $t1, $t2 addi $v0, $0, 9 syscall stack: beq $t0, $s0, list_sum la $a0, element_prompt addi $v0, $0, 4 syscall addi $v0, $0, 5 syscall sw $v0, to_store lw $t5, to_store addi $sp, $sp, -4 sw $t5, 0($sp) addi $t0, $t0, 1 j stack list_sum: beq $s0, 0, average lw $t6, sum lw $t7, 0($sp) addi $sp, $sp, 4 add $t6, $t7, $t6 sw $t6, sum addi $s0, $s0, -1 j list_sum average: lw $t0, sum div $t0, $s0 mflo $t0 sw $t0, avg lw $a0, avg addi $v0, $0, 1 syscall
okay, had only 1 bug , one-liner doing pretty well.
however, there weren't many comments in code, reading/analyzing it, added some.
i should mention did this, able spot bug visual inspection , review. is, able find bug , annotate along fix alone.
so, i'd didn't need step code debugger. after applying fix, ran correctly first time.
i answered similar question here: mips questions writing assembly call functions on array sum/product on array
also, please see answer here: mips linked list amongst other things, has howto on writing clean mips/asm code, based on own personal experience.
i created 2 versions of code. 1 minimal changes , bug fix. and, another, tightened , simplified bit. please pardon gratuitous style cleanups.
here's code bug/fix annotation:
.data # note/bug: due alignment issues put .word directives _before_ # [variable length] .asciiz directives size: .word 0 to_store: .word 0 sum: .word 0 avg: .word 0 size_prompt: .asciiz "enter number of elements: " element_prompt: .asciiz "enter element: " msg_space: .asciiz " " .text .globl main main: # prints prompt la $a0,size_prompt addi $v0,$0,4 syscall # gets input user addi $v0,$0,5 syscall sw $v0,size addi $t0,$0,0 # initialise = 0 # creates list lw $s0,size # array count addi $t1,$0,4 # 4 mult $s0,$t1 # count * 4 mflo $t2 # offset add $a0,$t1,$t2 addi $v0,$0,9 syscall stack: beq $t0,$s0,list_sum # done number input? if yes, fly # prompt user list element la $a0,element_prompt addi $v0,$0,4 syscall # read in element value addi $v0,$0,5 syscall sw $v0,to_store lw $t5,to_store # push element stack addi $sp,$sp,-4 sw $t5,0($sp) addi $t0,$t0,1 # advance array index j stack # sum of array elements list_sum: beq $s0,0,average # @ end? if yes, fly lw $t6,sum # previous sum lw $t7,0($sp) # next array element value addi $sp,$sp,4 # advance array pointer add $t6,$t7,$t6 # sum += array[i] sw $t6,sum # store addi $s0,$s0,-1 # bump down _count_ j list_sum # note/bug: in list_sum loop above, s0 being decremented, when # here _always_ 0 average: lw $t0,sum # sum # print sum li $v0,1 move $a0,$t0 syscall # note/fix: restore count value lw $s0,size div $t0,$s0 # divide count mflo $t0 sw $t0,avg # store average li $v0,4 la $a0,msg_space syscall # print average lw $a0,avg addi $v0,$0,1 syscall exit: li $v0,10 # exit program syscall
here's take on cleanup.
mips has many registers, when can used, intermediate results can preserved.
for example, note in summation loop, different register used decrement, $s0
remains. also, able use registers hold values used memory locations [except stack usage]
.data size_prompt: .asciiz "enter number of elements: " element_prompt: .asciiz "enter element: " msg_space: .asciiz " " .text .globl main main: # prompt user number of elements la $a0,size_prompt li $v0,4 syscall # array count user li $v0,5 syscall move $s0,$v0 # save array count li $t0,0 # = 0 stack: beq $t0,$s0,sumlist # input done (i.e. >= count)? if yes, fly # prompt user list element la $a0,element_prompt li $v0,4 syscall # read in element value li $v0,5 syscall # push element stack addi $sp,$sp,-4 sw $v0,0($sp) addi $t0,$t0,1 # += 1 j stack # sum of array elements # t6 -- sum value sumlist: li $t6,0 # sum = 0 move $t4,$s0 # count sumlist_loop: beqz $t4,average # @ end? if yes, fly # pop element off stack lw $t7,0($sp) # next array element value addi $sp,$sp,4 # advance array pointer add $t6,$t6,$t7 # sum += array[i] addi $t4,$t4,-1 # bump down count j sumlist_loop # average # t6 -- sum value # t5 -- average value average: # print sum li $v0,1 move $a0,$t6 # sum syscall div $t6,$s0 # compute sum / count mflo $t5 # retrieve # output space li $v0,4 la $a0,msg_space syscall # print average move $a0,$t5 li $v0,1 syscall exit: li $v0,10 # exit program syscall
Comments
Post a Comment