2014-09-13 2 views
-1

MIPS 어셈블리 언어에서 fibonacci 함수를 구현하려고합니다. 아래에 몇 가지 코드를 작성했는데 오류없이 런타임 실행을 통과하고 각 반복에서 $ a0의 n 값이 올바르게 표시되는지 확인할 수 있습니다. 그러나, $의 V0에 배치 결과는 2MIPS 어셈블리의 피보나치가 올바른 대답을 반환하지 않습니다.

코드를 반환하는 매우 마지막 반복까지 설정되지 않습니다 : 당신 ABI에 따라

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

을, 스택 포인터는 첫 번째 을 가리켜 야합니다

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

같은 라인을 피해야한다 그래서 경우에 프로그램이 인터럽트 핸들러는 사용자 스택을 사용하는 시스템에서 중단됩니다, 스택에 해결합니다.

코드와 더 큰 문제는 함수가이 n>1 호출 할 때 반환하는 방법입니다 :

syscall   # return 

은 단순히 잘못된 것입니다. 돌아올 syscall을하지 마십시오! 당신이 n<=1 경우 제대로

jr $ra    # return to body 

을 사용하기 때문에 이것은 특히 수수께끼이다.

대신 syscall

, 당신은

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