Mips Рекурсивное назначение - PullRequest
0 голосов
/ 30 марта 2020

Я надеюсь, что все в порядке в эти 19 раз. Я работаю над заданием, и я надеюсь, что кто-то может указать, где я иду не так. Я принимаю число в программе MIPS, которое будет помещено в рекурсивную функцию, которая возвращает следующее: Correct Output

Рекомендации: Рекурсивная функция принимает одно положительное целое число в качестве входного аргумента и определяется как:

recurse (n) = 1, если n = 0

recurse (n) = n * Recurse (n-1) + 1, если n> 0

Мой рекурсивный процесс идет хорошо, но я чувствую, что теряюсь в возвратах, когда функция раскручивается. Я также уверен, что многое из того, что я делаю, может выглядеть очень грязно, так как я новичок в MIPS. Вот моя версия:

My Output

Вот мой код:

PRINT_STRNG = 4
PRINT_INT   = 1
PRINT_CHAR  = 11
READ_CHAR   = 12
READ_STRNG  = 8
READ_INT    = 5
TERMINATE   = 10
NEWLINE     = 10

.data
    prompt1: .asciiz "\nPlease enter a decimal integer between 1 and 12 (or 0 to stop): "
    terminating: .asciiz "\nTerminating!"
    recursing: .asciiz "recursing "
    returning: .asciiz "returning "
    newLine: .asciiz "\n"
.text
    main:
        jal clearRegs
        li $t0, 4
        jal promptNumber
        move $a1, $v0
        beq $a1, $zero, exit
        move $t2, $a1 # $t2 has n
        mul $t1, $a1, $t0 # $t1 has the spaces
        jal factPlusOne
        j main
    promptNumber:
        # Prompt the user for first decimal
        li $v0, PRINT_STRNG
        la $a0, prompt1
        syscall
        # Get the user's first decimal
        li $v0, READ_INT
        syscall

        # Print new line after
        li $v0, PRINT_STRNG
        la $a0, newLine
        syscall

        jr $ra
    printRecursingSpaces:
        # $ra now points to below print spaces

        # Prints the spaces before the recursing messages
        blez $t1, printRecursing

        li $a0, 32
        li $v0, 11  # syscall number for printing character
        syscall

        addi $t1, $t1, -1
        j printRecursingSpaces
    printReturningSpaces:
        # Prints the spaces before the returning messages
        blez $t1, printReturning

        li $a0, 32
        li $v0, 11  # syscall number for printing character
        syscall

        addi $t1, $t1, -1
        j printReturningSpaces
    factPlusOne:
        # Tests to enter recursion or end recursion
        move $s0, $ra
        jal printRecursingSpaces
        bgtz $a1, recurse
        li $t3, 1
        jr $s0
    recurse:
        addi $sp, $sp, -8
        sw $ra, 4($sp)
        sw $a1, 0($sp)
        addi $a1, $a1, -1
        mul $t1, $a1, $t0
        jal factPlusOne
        lw $v1, 0($sp)
        mul $t4, $t3, $v1
        addi $t4, $t4, 1 # $t3 has n * Recurse(n-1) + 1
        mul $t1, $t4, $t0
        jal printReturningSpaces
        lw $ra, 4($sp)
        addi $sp, $sp, 8
        jr $ra
    printRecursing:
        # Prints the recursing message
        li $v0, PRINT_STRNG
        la $a0, recursing
        syscall

        # Print the n
        li $v0, PRINT_INT
        addi $a0, $a1, 0
        syscall

        # Prints a new line
        li $v0, PRINT_STRNG
        la $a0, newLine
        syscall
        jr $ra
    printReturning:
        # Prints the returning message
        li $v0, PRINT_STRNG
        la $a0, returning
        syscall

        # Print the n
        li $v0, PRINT_INT
        addi $a0, $t4, 0
        syscall

        # Prints a new line
        li $v0, PRINT_STRNG
        la $a0, newLine
        syscall
        jr $ra
    clearRegs:
        sub $v0, $v0, $v0
        sub $v1, $v1, $v1
        sub $a0, $a0, $a0
        sub $a1, $a1, $a1
        sub $t0, $t0, $t0
        sub $t1, $t1, $t1
        sub $t2, $t2, $t2
        sub $t3, $t3, $t3
        sub $t4, $t4, $t4
        sub $s0, $s0, $s0
        jr $ra
    exit:
        # Show terminating message and exit program
        li $v0, PRINT_STRNG
        la $a0, terminating
        syscall
        li $v0, TERMINATE
        syscall

Собираюсь взломать его в течение следующих нескольких часов , Я ценю любую помощь и надеюсь, что у всех будет хорошее воскресенье. Спасибо!

1 Ответ

0 голосов
/ 09 апреля 2020

Я закончил тем, что исправил это, мне просто пришлось воспользоваться asp концепцией, что где бы вам ни понадобилось сохранять значение $ ra, создавайте переменную стека. Рабочий код ниже:

PRINT_STRNG = 4
PRINT_INT   = 1
PRINT_CHAR  = 11
READ_STRNG  = 8
READ_INT    = 5
TERMINATE   = 10
NEWLINE     = 10

.data
    prompt1: .asciiz "\nPlease enter a decimal integer between 1 and 6 (or 0 to stop): "
    terminating: .asciiz "\nTerminating!"
    recursing: .asciiz "recursing "
    returning: .asciiz "returning "
    newLine: .asciiz "\n"
    theNumber: .word 0
.text
    main:
    li $t0, 4
    jal promptNumber
    lw $a1, theNumber
    bgt $a1, 6, main    # If >6 is entered
    beq $a1, $zero, exit        # If 0 is entered
    blez $a1, main      # If <0 is entered
    mul $t1, $a1, $t0 # $t1 has the spaces
    jal factPlusOne
    jal printReturningSpaces # for the last result
    j main
promptNumber:
    # Prompt the user for first decimal
    li $v0, PRINT_STRNG
    la $a0, prompt1
    syscall
    # Get the user's first decimal
    li $v0, READ_INT
    syscall

    sw $v0, theNumber
    # Print new line after
    li $v0, PRINT_STRNG
    la $a0, newLine
    syscall

    jr $ra
printRecursingSpaces:
    # Prints the spaces before the recursing messages
    blez $t1, printRecursing

    li $a0, 32
    li $v0, 11  # syscall number for printing character
    syscall

    addi $t1, $t1, -1
    j printRecursingSpaces
printReturningSpaces:
    # Prints the spaces before the returning messages
    blez $t1, printReturning

    li $a0, 32
    li $v0, 11  # syscall number for printing character
    syscall

    addi $t1, $t1, -1
    j printReturningSpaces
factPlusOne:
    # Tests to enter recursion or end recursion, saves $ra
    addi $sp, $sp, -4
    sw $ra, 0($sp)
    jal printRecursingSpaces
    lw $ra, 0($sp)
    addi $sp, $sp, 4

    bgtz $a1, recurse
    li $t3, 1
    jr $ra
recurse:
    # wind up recursion
    addi $sp, $sp, -8
    sw $ra, 4($sp)
    sw $a1, 0($sp)
    addi $a1, $a1, -1
    mul $t1, $a1, $t0
    jal factPlusOne

    # unwind recursion
    lw $v1, 0($sp)
    jal printReturningSpaces
    mul $t1, $v1, $t0
    mul $t3, $t3, $v1
    addi $t3, $t3, 1
    lw $ra, 4($sp)
    addi $sp, $sp, 8
    jr $ra
printRecursing:
    # Prints the recursing message
    li $v0, PRINT_STRNG
    la $a0, recursing
    syscall

    # Print the n
    li $v0, PRINT_INT
    addi $a0, $a1, 0
    syscall

    # Prints a new line
    li $v0, PRINT_STRNG
    la $a0, newLine
    syscall
    jr $ra
printReturning:
    # Prints the returning message
    li $v0, PRINT_STRNG
    la $a0, returning
    syscall

    # Print the n
    li $v0, PRINT_INT
    addi $a0, $t3, 0
    syscall

    # Prints a new line
    li $v0, PRINT_STRNG
    la $a0, newLine
    syscall
    jr $ra
exit:
    # Show terminating message and exit program
    li $v0, PRINT_STRNG
    la $a0, terminating
    syscall
    li $v0, TERMINATE
    syscall
...