简体   繁体   English

在子程序中添加到数组(MIPS /程序集)

[英]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. 我可以将第一个有效值(正数并可以被3整除)进入数组,但是下一个有效项不起作用。 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. 我可以输入一个有效数字,然后输入一个无效数字,程序可以正常运行,但是两个有效数字会使Spim停止工作。 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. 感谢我如何修复createArray的任何技巧。

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). 您的主要问题是使用了.word 80 ,它仅保留一个值为80的单词。您可能是.space 80最多保留20个单词的空间(这似乎是代码中的限制)。

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). 例如,你可以使用$t0作为计数器createArray而这不会保留子程序,不按约定和事实上不受你的代码(包括divisibleBy3checkNumPositive摧毁它)。

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. 类似的问题是在嵌套的子例程调用中没有适当保留$ra ,因此createArray的返回地址被从那里调用的子例程覆盖。

I assume the intent of the assignment was to teach you about these nuances. 我认为作业的目的是教您这些细微差别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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