[英]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-2
, D1
持有fib(n-1)
, D0
為fib(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.