簡體   English   中英

匯編語言遞歸:結果始終打印為零; 遞歸方法中的邏輯問題?

[英]Assembly Language Recursion: Result always printing zero; issue with logic in recursive method?

我目前正在學習匯編語言(Motorola 68K匯編程序)課程。 我有一個項目,負責打印最多30個數字的斐波那契數的結果。例如,如果用戶輸入4,則結果應為3(因為它是前兩個數字的總和)。 但是,我的主程序(prog4.s)連續打印出0。問題與遞歸方法的邏輯有關嗎? 問題出在其他地方嗎? 這是我的遞歸方法代碼(fib.s)

* fib.s
* long fib(int n) {
*     if(n==0) { 
*      return 0;
*     }
*     else if(n==1) {
*      return 1;
*     }
*     return fib(n-1) + fib(n-2);
* }

ORG $7000

fib:
    link      A6,#0
    movem.l   D1-D2,-(SP)
    move.w    8(A6),D1
    TST.w     D1
    BNE       next
    BRA       out

next:
    cmpi.w    #1,D1
    BNE       recurse
    add.w     #1,D0
    BRA       out

recurse:
    move.w    D1,D2
    subq.w    #1,D1
    move.w    D1,-(SP)
    JSR       fib
    move.w    D0,D1      * save copy of fib(n-1)

    adda.l    #2,SP

    subq.w    #2,D2
    move.w    D2,-(SP)
    JSR       fib
    add.w     D2,D1
    add.w     D1,D0        * return fib(n-1) + fib(n-2)

    adda.l    #2,SP

out:
    movem.l   (SP)+,D1-D2
    unlk      A6
    rts

    end

這是我的程序代碼,該程序調用fib.s

fib:   EQU   $7000
start: initIO
setEVT

lineout     title
lineout     prompt
linein      buffer
cvta2       buffer,D1

* Place parameter on the stack and move the stack pointer
move.w      D1,-(SP)

*Jump to the fib subroutine
JSR         fib

*Pop starting parameter off the stack 
adda.l      #2,SP

cvt2a       buffer,#6
stripp      buffer,#6
lea         buffer,A0
adda.l      D0,A0
clr.b       (A0)
lineout     answer

break

prompt:     dc.b 'Enter a number between 1 and 30: ',0
answer:     dc.b 'The Fibonacci number is: '
buffer:     ds.b  80
       end

需要注意的一點:我需要使用在fib.s中注釋掉的算法。 任何幫助/建議將不勝感激。

您的程序幾乎是正確的。
問題不在自身遞歸的邏輯之內,而是您如何返回每次調用計算得出的值。
與調試器一起進行的兩個跟蹤會話將幫助您發現問題。

我先給你一個提示。 這些線

add.w     D1,D2      *fib(n-1) + fib(n-2)
add.w     D2,D0      *add fib(n-2)

不要按照評論說的做。
D2持有n-2D1持有fib(n-1)D0fib(n-2)因此最終結果為fib(n-1) + fib(n-2) + n - 2 只需將它們替換為ADD.W D1, D0即可返回fib(n-1) + fib(n-2)

還有其他兩個錯誤,但是您如何返回其他兩種情況的值( n = 0和n = 1)。

強烈建議您嘗試使用Easy68k隨附的68k模擬器自行調試對fib(0)fib(1)的調用。
一個重要的建議:在開始仿真之前,將D0設置為隨機值(例如:$ 55555555),並使用F7跟蹤執行。

如果您找不到其他錯誤,這里就是

用於返回1對於n = 1的情況下的指令是ADD.W #1, D0取決於以前的值D0
它應該是MOVE.W #1, D0
如果n = 0,則函數out不修改D0情況下分支到out ,應將D0設置為零。
類似於MOVE.W #0, D0或其他調零習慣。

問題出在調用程序prog4.s中。 您正確讀入了值,但是您將錯誤的寄存器傳遞給了堆棧。 宏linein將二進制補碼整數存儲在D0中,而不是D1中。 由於D1在您傳入之前為零,因此每次都會返回零。 這是調用程序的正確代碼:

fib:    EQU             $7000
start:  initIO                  * Initialize (required for I/O)
        setEVT                  * Error handling routines
*       initF                   * For floating point macros only


lineout         title
lineout         prompt
linein          buffer
cvta2           buffer,D0


* Place parameters on the stack and move the stack pointer
move.w          D0,-(SP)


* Jump to the fib subroutine
JSR             fib


* Pop starting parameters off of the stack
adda.l          #2,SP


cvt2a           buffer,#6
stripp          buffer,#6
lea             buffer,A0
adda.l          D0,A0           * Sets A0 to the address of D0
clr.b           (A0)
lineout         answer


break                           * Terminate execution
*
*----------------------------------------------------------------------
*       Storage declarations


title:  dc.b    'Program #4, Christopher Moussa, cssc0702',0
prompt: dc.b    'Enter a number between 1 and 30: ',0
answer: dc.b    'The Fibonacci number is: '
buffer: ds.b    80
    end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM