2012-10-20 2 views
0

Я пытаюсь добавить значения в массив внутри подпрограммы. Я могу получить первое допустимое значение (положительное число и делимое на 3) в массив, но следующие допустимые записи не работают. Я могу ввести действительное число, а затем ввести недопустимый номер, и программа работает нормально, но два действительных числа заставляют Spim перестать работать. Я потратил несколько часов, пытаясь понять это, но не повезло. Переключение с одной подпрограммы является обязательным для задания, у меня есть рабочая программа, но у меня нет всех ненужных (по-моему) подпрограмм.Добавление в массив в подпрограмме (MIPS/Assembly)

.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, оценили, спасибо.

ответ

1

Основная проблема заключается в том, что вы использовали .word 80, который сохраняет только одно слово со значением 80. Вероятно, вы имели в виду .space 80, чтобы зарезервировать место на 20 слов (что, по-видимому, является пределом, установленным в вашем коде).

Дальнейшая проблема заключается в том, что вы не следуете соглашениям о том, какие регистры необходимо сохранить.

Например, вы используете $t0 в качестве счетчика в createArray и что не сохранилось по подпрограммам, а не по соглашению и де-факто не ваш кода (как divisibleBy3 и checkNumPositive уничтожить его).

Аналогичная проблема с неправильным сохранением $ra во вложенных вызовах подпрограммы, поэтому адрес возврата для createArray перезаписывается подпрограммами, вызываемыми оттуда.

Я предполагаю, что целью задания было научить вас об этих нюансах.

Смежные вопросы