0

サブルーチン内の配列に値を追加しようとしています。最初の有効な値 (正の数で 3 で割り切れる) を配列に取得できますが、次の有効なエントリは機能しません。有効な数字を入力してから無効な数字を入力すると、プログラムは正常に動作しますが、有効な数字が 2 つあると Spim が動作しなくなります。私はそれを理解しようとして数時間を費やしましたが、運がありません。1 つのサブルーチンからのジャンプは割り当ての要件です。私は作業プログラムを持っていますが、不要な (私の意見では) サブルーチンがすべてありません。

    .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

createArray を修正する方法に関するヒントをいただければ幸いです。

4

1 に答える 1

1

あなたの主な問題は.word 80、値が 80 の単一の単語のみを予約する使用です。おそらく.space 80、最大 20 単語のスペースを予約するつもりでした (これは、コードで強制されている制限のようです)。

さらに問題は、どのレジスタを保存する必要があるかについての規則に従っていないことです。

たとえば、$t0as counter inを使用しcreateArray、それはサブルーチン全体で保存されません。慣例ではなく、事実上、コードではありません (両方ともdivisibleBy3それをcheckNumPositive破棄します)。

ネストされたサブルーチン呼び出しで適切に保存$raされないという同様の問題があります。そのため、そこから呼び出されたサブルーチンによって戻りアドレスcreateArrayが上書きされます。

この課題の意図は、これらのニュアンスについて教えることだったと思います。

于 2012-10-22T01:29:41.417 に答える