Recursive Fibonacci in Assembly

后端 未结 3 1742
旧时难觅i
旧时难觅i 2021-01-05 09:54

I\'m attempting to implement a recursive Fibonacci program in Assembly. However, my program crashes, with an unhandled exception, and I can\'t seem to pick out the problem.

3条回答
  •  Happy的楠姐
    2021-01-05 10:13

    Several problems:

    • if you are going to pass parameters on the stack, you don't have the right (standard) function entry, so EBP points to the wrong place
    • you aren't saving the argument value properly in edx

    Here's what I think you wanted, assuming you are passing parameters on the stack (best to add a comment to each instruction making it clear what you think it does):

    Fibonacci proc
      PUSH EBP          ; save previous frame pointer
      MOV  EBP, ESP     ; set current frame pointer
    
      MOV  EAX, [EBP+8] ; get argument N
      CMP  EAX, 1       ; N<=1?
      JA   Recurse      ; no, compute it recursively
      MOV  ECX, 1       ; yes, Fib(1)--> 1
      JMP  exit
    
    Recurse:
      DEC  EAX          ; = N-1
      MOV  EDX, EAX     ; = N-1
      PUSH EDX          ; save N-1
      PUSH EAX          ; set argument = N-1
      CALL Fibonacci    ; compute Fib(N-1) to ECX
      POP  EAX          ; pop N-1
      DEC  EAX          ; = N-2
      PUSH ECX          ; save Fib(N-1)
      PUSH EAX          ; set argument = N-2
      CALL Fibonacci    ; compute Fib(N-2) to ECX
      POP  EAX          ; = Fib(N-1)
      ADD  ECX, EAX     ; = Fib(N-1)+FIB(N-2)
    exit:
      MOV  ESP,EBP      ; reset stack to value at function entry 
      POP  EBP          ; restore caller's frame pointer
      RET               ; and return
    

    But you don't have to pass the parameters on the stack. It is more efficient to use the registers:

    Fibonacci proc ; computes Fib(EAX) --> EAX; do not call with EAX==0
      CMP  EAX, 1      ; N<=1?
      JBE  exit        ; yes, we have the answer
      DEC  EAX         ; = N-1
      PUSH EAX         ; save N-1
      CALL Fibonacci   ; computing FIB(n-1)to EAX
      XCHG EAX,0[ESP]  ; swap FIB(n-1) for saved N-1 (You'll love this instruction, look it up in the Intel manual)
      DEC  EAX         ; = N-2
      CALL Fibonacci   ; computing FIB(N-2) to EAX
      POP  ECX         ; = FIB(N-1)
      ADD  EAX,ECX     ; = FIB(N-1)+FIB(N-2)
    exit:
      RET
    

提交回复
热议问题