📄 fib.asm
字号:
DATA SEGMENT
;用于存放结果,5个菲波那切契数
RESULT DW 5 DUP(?)
STR DB 'greater than 10000 and smaller than 65535 !',0DH,0AH,0DH,0AH,'$';字符串STR1,用于输出提示信息
STR2 DB 0DH,0AH,'The five fib-numbers ',0AH,'$'
STR3 DB 0DH,0AH,'Please input a legal decimal number !',0DH,0AH,'$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
;subfuction INPUT
;输入子程序,输入一个不大于60000的数,以10进制形式输入,16进制形式存放在BX中
INPUT PROC FAR
MOV BX,0
;循环计数
MOV CX,05H
;输入一个位
INPUTANUMBER:
MOV AH,01H
INT 21H
;判断是否小于0
SUB AL,30H
JL REINPUT
CMP AL,09H
;判断是否大于9
JG REINPUT
CBW
;把原来的数乘10再加上新输入的数
XCHG AX,BX
PUSH CX
MOV CX,10D
MUL CX
POP CX
XCHG AX,BX
ADD BX,AX
;计数器-1
DEC CX
;循环输入从高到低的5个位数
JNZ INPUTANUMBER
JMP EXIT
;输出提示符并等待重新输入
REINPUT:
LEA DX,STR3
MOV AH,09H
INT 21H
MOV CX,05H
JMP INPUTANUMBER
EXIT:
RET
INPUT ENDP
;subfuction GETFIB
;获取不超过输入数的最大菲波那契数,存于DX
GETFIB PROC FAR
MOV AX,1
MOV DX,1
PUSH AX
GETFIBLOOP:
POP AX
;通过相加交换循环不断获取更大的菲波那契数
ADD AX,DX
XCHG AX,DX
PUSH AX
MOV CL,AH
SUB AX,AX
MOV AL,DH
CMP CX,AX
;若相加后变小说明溢出,退出计算
JG ENDGETFIB
;按先高8位,后低8位的顺序判断是否结果超过了输入的数;
POP AX
PUSH AX
SUB CX,CX
SUB AX,AX
MOV CL,DH
MOV AL,BH
CMP CX,AX
;高8位小于,继续获得更大菲波那契数
JL GETFIBLOOP
CMP CX,AX
;高8位大于,已经超出,
JG ENDGETFIB
;高8位相等,继续判断低8位
MOV CL,DL
MOV AL,BL
CMP CX,AX
;小于,继续获得更大菲波那契数
JL GETFIBLOOP
ENDGETFIB:
POP AX
RET
GETFIB ENDP
;subfuction CRLF
;打印回车换行子程序
CRLF PROC FAR
PUSH DX
PUSH AX
MOV DL,0DH
MOV AH,02H
INT 21H
MOV DL,0AH
INT 21H
POP AX
POP DX
RET
CRLF ENDP
;subfuction GERONERESULT
;获取一个菲波那契数子程序
GETONERESULT PROC FAR
PUSH DX
PUSH AX
PUSH CX
;把RESULT地址放在BX中
LEA BX,RESULT
;把一个菲波那契数转换位10进制准备输出
GETRESULTLOOP:
MOV DX,0
MOV CX,10D
;除以10得余数,即低位
DIV CX
;地址+1
MOV [BX],DX
INC BX
CMP AX,0
JNZ GETRESULTLOOP
;输出一个菲波那契数
CALL FAR PTR OUTPUTONE
;CX,AX,DX依次出栈
POP CX
POP AX
POP DX
RET
GETONERESULT ENDP
;subfuction GETRESULTS
;获取结果子程序
GETRESULTS PROC FAR
;先得到最第一个菲波那契数
CALL FAR PTR GETONERESULT
;得到余下4个菲波那契数
MOV CX,04H
GETRESULTSROOP:
SUB DX,AX
XCHG DX,AX
CALL FAR PTR CRLF
CALL FAR PTR GETONERESULT
DEC CX
JNZ GETRESULTSROOP
RET
GETRESULTS ENDP
;subfuction OUTPUTON
;输出一个菲波那契数的子程序
OUTPUTONE PROC FAR
MOV CX,5
;循环输出一个数的5个位
;RESULT地址放在BX中
LEA BX,RESULT
ADD BX,4
;从高位开始输出
OUTPUTONELOOP:
MOV DX,[BX]
ADD DX,30H
MOV AH,02H
INT 21H
DEC BX
;地址-1
DEC CX
JNZ OUTPUTONELOOP
RET
OUTPUTONE ENDP
;main
MAIN:
MOV AX,DATA
MOV DS,AX ;设置数据段
LEA DX, STR ;输出提示符
MOV AH,09H
INT 21H
CALL FAR PTR INPUT ;调用输入子程序
CALL FAR PTR CRLF ;调用回车换行子程序
LEA DX,STR2 ;输出提示符
MOV AH,09H
INT 21H
CALL FAR PTR GETFIB ;计算菲波那契数
CALL FAR PTR GETRESULTS ;获取菲波那契数
MOV AH,01H ;等待输入一个字符结束
INT 21H
MOV AH,4CH ;调用DOS功能退出
INT 21H
CODE ENDS ;代码段结束
END MAIN ;结束
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -