assembly - I want to calculate the average value of a list on MIPS -


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