简体   繁体   中英

Adding to an array in a subroutine(MIPS/Assembly)

I'm trying to add values to an array inside a subroutine. I can get the first valid value(positive number and divisible by 3) into the array, but the next valid entries don't work. I can enter a valid number and then enter an invalid number and the program works fine, but two valid numbers makes Spim stop working. I've spent a few hours trying to figure it out but no luck. The jumping from one subroutine is a requirement for the assignment, I have a working program but lacks all the unnecessary(in my opinion) subroutines.

    .data
    array1:                 .word   80
    EnterARVal:             .asciiz "Please enter a number:\t"
    space:                  .asciiz " "
    errormessage:           .asciiz "*****Error: "
    notpos:                 .asciiz " is not a positive number.\n"
    notdiv3:                .asciiz " is not divisible by 3.\n"
    numadded:               .asciiz " added to array.\n"
    EnterElem:              .asciiz "Enter number "
    ARReverse:              .asciiz "The contents of the array in reverse orders is:\n"
    InvalidAR:              .asciiz "Invalid number of array elements, please try again.\n"                     
                    .text



main:                   
                    la  $s0, array1 #array1 pointer
                    li  $t0, 1
begin:                  

                    jal readNum #go to readNum subroutine

                    add $a0, $0, $v0    #stores readNum input to $a0

                    jal verifySize  #jumps to verifySize subroutine

                    add $t1, $v1, $0    #stores 0 or 1 value to $t1

                    beq $t1, $0, begin  #starts over if t1 is 0 or false

                    beq $t1, $t0, numok #goes to numok if t1 is 1 or true

                    numok:  add     $a0, $0, $a0
                            add     $a1, $0, $s0
                            jal     createArray

                 j exit


readNum:                li  $v0, 4
                    la  $a0, EnterARVal
                    syscall

                    li  $v0, 5
                    syscall

                    add $v0, $v0, $0

                    j   $ra

verifySize:             add $t1, $0, $a0

                    li  $t2, 20 
                    li  $t3, 1
                    li  $t4, 0
                    li  $t5, 1

                    slt $t6, $t1, $t3
                    beq $t6, $t3, toolow

                    sgt $t7, $t1, $t2
                    beq $t7, $t3, toohigh
                    beq $t7, $t4, oknum

                    oknum:
                    add $v1, $t5, $0

                    j   $ra

                    toolow:
                    li  $v0, 4
                    la  $a0, InvalidAR
                    syscall

                    add $v1, $t4, $0
                    j   $ra

                    toohigh:
                    li  $v0, 4
                    la  $a0, InvalidAR
                    syscall

                    add $v1, $t4, $0                    
                    j   $ra


createArray:            add     $s1, $a0, $0
                    add     $s0, $a1, $0
                    li  $t0, 0 #counter
                    li  $t2, 1

                    add $a0, $s1, $0
                    li  $v0, 1
                    syscall

    makingarray:        beq $t0, $s1, arraydone

                    jal readNum #go to readNum subroutine

                    add $a0, $v0, $0    #stores number from readNum to $a0
                    jal checkNumPositive    #jump to checkNumPositive subroutine

                    add $t1, $v0, $0
                    beq $t1, $0, positivenum    #if number is positive go to positivenum
                    beq $t1, $t2, notpositive

                    positivenum:
                    jal divisibleBy3
                    add $t4, $v0, $0

                    beq $t4, $0, notdivisibleby3


                        sw  $a0, 0($s0)

                        li  $v0, 1
                        syscall

                        li  $v0, 4
                        la  $a0, numadded
                        syscall

                        add $s0, $s0, 4
                        add $t0, $t0, 1
                        j   makingarray

                        arraydone:                  
                        add $v0, $s0, $0
                        j   $ra                         

                        notpositive:
                        li  $v0, 4
                        la  $a0, notpos
                        syscall

                        j makingarray

                        notdivisibleby3:
                        li  $v0, 4
                        la  $a0, notdiv3
                        syscall
                        j makingarray



#reverseArray:





divisibleBy3:           add $t0, $a0, $0
                    li  $t1, 3

                    div $t0, $t1
                    mfhi    $t2
                    mflo    $t3

                    seq     $t4, $t2, $0

                    add     $v0, $t4, $0
                    j       $ra


checkNumPositive:       li  $t0, 0

                    slt $t1, $a0, $0    #set t1 to 1 if number is less than 0

                    add $v0, $t1, $t0
                    j   $ra


exit:                   li  $v0, 10
                    syscall

Any tips with how I can fix createArray is appreciated, thanks.

Your primary problem is you used .word 80 which only reserves a single word with value 80. You probably meant .space 80 to reserve space for up to 20 words (which seems to be the limit enforced in your code).

Further problem is you are not following conventions about which registers need to be preserved.

For example, you use $t0 as counter in createArray and that's not preserved across subroutines, not by convention and de facto not by your code (both divisibleBy3 and checkNumPositive destroy it).

Similar problem with not properly preserving $ra in nested subroutine calls, as such the return address for createArray is overwritten by the subroutines invoked from there.

I assume the intent of the assignment was to teach you about these nuances.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM