2014-09-13 2 views
-1

Я пытаюсь реализовать функцию фибоначчи на языке ассемблера MIPS. Я написал код ниже, и на нем выполняется выполнение во время выполнения без каких-либо ошибок, и я могу видеть, что значение n в $ a0 правильно тикает вниз на каждой итерации. Тем не менее, результат помещается в $ v0 никогда не устанавливается до самой последней итерации, где она возвращает 2Фибоначчи в сборке MIPS не возвращает правильный ответ

код:

data: 
    addi $a0, $zero, 10 

fib: 
    slti $t0, $a0, 2  # check n <= 1 
    beq $t0, $zero, body # if previous statement was false, continue procedure 
    addi $v0, $zero, 1 # else return 1 

    jr $ra    # return to body 


body: 
    addi $sp, $sp, -16 # make room for 4 registers in stack 
    sw $a0, 0($sp)  # save $a0 = n, to stack 
    sw $ra, 4($sp)  # save return address to stack 

    addi $a0, $a0, -1 # $a0 = n - 1 
    jal fib   # invoke fib(n-1) and save return address 

    sw $v0, 8($sp)  # $v0 = fib(n-1), save to stack 

    addi $a0, $a0, -1 # $a0 = n - 2 
    jal fib   # invoke fib(n-2) and save return address 

    sw $v0, 12($sp) # $v0 = fib(n-2), save to stack 

    lw $t0, 8($sp)  # $t0 = fib(n-1) 
    lw $t1, 12($sp) # $t1 = fib(n-2) 
    addi $sp, $sp, 16 # pop from stack 

    add $v0, $t0, $t1 # $v0 = fib(n-1) + fib(n-2) 

    syscall   # return 
+0

Что ваш вопрос? Какая линия не делает то, что вы ожидали? –

+0

Проблема в том, что для всех входов> 2 результат, хранящийся в $ v0 при завершении, равен 2, и я не уверен в точной строке – Tarlen

+0

Ну, тогда вам нужно отлаживать еще несколько. Когда вы дойдете до такой степени, что какая-то линия не делает то, что вы ожидаете, вернитесь, и мы сможем помочь. –

ответ

1

В зависимости от вашего ABI, указатель стека должен указывать на первый пустой адрес в стеке, так как линии

sw $a0, 0($sp)  # save $a0 = n, to stack 

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

Большая проблема с вашим кодом является способом ваша функция возвращает, когда она была вызвана с n>1:

syscall   # return 

просто неправильно. Вы не возвращаетесь syscall! Это особенно озадачивает, так как вы используете

jr $ra    # return to body 

правильно в n<=1 случае.

Вместо syscall, вам нужно использовать

lw $ra, 4($sp)  #restore link register 
addi $sp, $sp, 16 #restore stack pointer 
jr $ra    #return