Assembly 如何在MASM(16位)中计算递归斐波那契序列的第25项
我正在用汇编语言(x86)用MASM(16位)编程递归斐波那契序列。代码如下:Assembly 如何在MASM(16位)中计算递归斐波那契序列的第25项,assembly,x86,masm,fibonacci,Assembly,X86,Masm,Fibonacci,我正在用汇编语言(x86)用MASM(16位)编程递归斐波那契序列。代码如下: DATAS SEGMENT TH DW 1; TIP DB 0DH,0AH, 'Please Input The Num Of Fibonacci Sequence Required:$' NUM DW 0; BUF DB 0; TIP1 DB 0DH,0AH,'The $' TIP2 DB 'th Of Fibonacci Sequence is: $' FORMA
DATAS SEGMENT
TH DW 1;
TIP DB 0DH,0AH, 'Please Input The Num Of Fibonacci Sequence Required:$'
NUM DW 0;
BUF DB 0;
TIP1 DB 0DH,0AH,'The $'
TIP2 DB 'th Of Fibonacci Sequence is: $'
FORMAT DB ' $'
FORMAT2 DB ' $'
ENDSTRING DB 'Do You Want To Continue The Process? Y/N $'
DATAS ENDS
STACKS SEGMENT
STACK DW 4096 DUP(?);
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MAIN PROC FAR
MOV AX,DATAS
MOV DS,AX
BEG:
MOV AX,3
INT 0AH
MOV AH,09H
LEA DX,TIP
INT 21H
MOV AH,01H;
INT 21H
;convert input to number
SUB AL,30H
PUSH CX
MOV CL,10
MUL CL
MOV BUF,AL
POP CX
MOV AH,01H
INT 21H
SUB AL,30H
ADD AL,BUF
MOV AH,0
MOV NUM,AX
XOR AX,AX
PUSH DS
PUSH AX
MOV SP,STACK
MOV AX,1
FIB:
PUSH AX;
CALL Fibonacci ;
;disply
push ax
push bx
push dx
mov ah,09h
lea dx,format2
int 21h
mov ah,09h
lea dx,tip1
int 21h
mov bx,th
call smallbinidec
mov ah,09h
lea dx,tip2
int 21h
pop dx
pop bx
pop ax
mov bx,ax ;disp
call binidec
call crlf
inc th
mov ax,th
cmp ax,num
jbe fib
call crlf
jmp exit
main endp
Fibonacci proc near
PUSH BP
MOV BP,SP
ADD SP,-4
;ax----the value of fibonacci,cx----the number of fibonacci
MOV CX,[BP+4]
CMP CX,2
JA CALCULATE ;if CX > 2 :recursive else :1
MOV AX,1
ADD SP,4
POP BP
RET 2
calculate:;sp = bp - 4
mov word ptr[bp-4],cx
dec cx
push cx
call Fibonacci
mov word ptr[bp-2],ax ;save f(x-1)
dec cx
push cx ;
call Fibonacci
add AX,word ptr[bp-2] ;f(x)= f(x-1)+ f(x-2)
;ax = f(x-2),word ptr[bp-2] = f(x-1)
mov cx,word ptr[bp-4]
add sp,4
pop bp
ret 2
Fibonacci endp
binidec proc near
mov cx, 10000d
call dec_div
mov cx, 1000d
call dec_div
mov cx, 100d
call dec_div
mov cx, 10d
call dec_div
mov cx, 1d
call dec_div
ret
binidec endp
smallbinidec proc near
mov cx, 10d
call dec_div
mov cx, 1d
call dec_div
ret
smallbinidec endp
dec_div proc near
mov ax, bx
mov dx, 0
div cx
mov bx, dx
mov dl, al
add dl, 30h
mov ah, 2
int 21h
ret
dec_div endp
CRLF PROC NEAR
MOV AH,02H
MOV DL,0DH
INT 21H
MOV AH,02H
MOV DL,0AH
INT 21H
RET
CRLF ENDP
exit:
MOV AH,4CH
INT 21H
CODES ENDS
END START
当计算n<25的项时,它确实工作得很好。然而,在计算斐波那契序列的第25项时出错了
经过分析,我认为问题在于像AX这样的寄存器只有16位,这使得它不能存储大于65535的数字(小于斐波那契序列的第25项)
一种简单的方法是在MASM(32位)中使用EAX
,而不是AX
。不幸的是,这是不允许的
因此,如何使此代码能够处理n>=25的术语
毕竟谢谢:)在过去,没有32位寄存器:我们将使用两个16位寄存器(或相同的寄存器两次)。您可以
添加
低位部分,然后ADC
高位部分。进位标志在MOV
指令后仍然有效(所有标志都有效),允许您存储低和的结果,并加载高部分。