80x86 汇编语言编程:斐波那契数列--大数处理
2016-01-25 12:10
387 查看
关于斐波那契数列,做而论道以前写过一个程序:
http://hi.baidu.com/do_sermon/item/6acb5f305f6efd08ceb9fee5
以前的数字大小,限于常用的 16 位数的范围。
有个题目,要求计算斐波那契数列的前30项:
http://zhidao.baidu.com/question/872588804722307132.html
算到第 25 项,就超出 16 位二进制数了。
再往下计算,需要用到 32 位数的运算方法。
做而论道编写的程序如下:
ASSUME CS:CC, DS:QW
;---------------------------
QW SEGMENT
MSG1 DB 13, 10, 'Please input n = $'
MSG9 DB 13, 10, 'Press any key to continue ... $'
CR_LF DB 13, 10, 36
X1 DW ?
X2 DW ?
X3 DB 0
N1 DW 0, 0
N2 DW 1, 0
X DW ?, ? ;BIN数字
Y DB 0, 0, 0, 0, 0 ;存放BCD码
QW ENDS
;---------------------------
CC SEGMENT
START:
MOV AX, QW
MOV DS, AX
LEA DX, MSG1
MOV AH, 9
INT 21H
CALL INPUT
MOV X1, CX
MOV X2, CX
CALL CR__LF
CAL:
INC X3
CMP X3, 47 ;第47项将溢出
JZ EXIT
MOV AX, N1
MOV DX, N1 + 2
ADD AX, N2
ADC DX, N2 + 2
MOV BX, N2
MOV N1, BX
MOV BX, N2 + 2
MOV N1 + 2, BX
MOV N2, AX
MOV N2 + 2, DX
MOV AX, X2
SUB AX, X1
INC AX
MOV BL, 10
DIV BL
MOV DX, AX
ADD DL, '0'
MOV AH, 2
INT 21H
MOV DL, DH
ADD DL, '0'
INT 21H
MOV DL, ':'
INT 21H
MOV DL, ' '
INT 21H
CALL OUTPUT
CALL CR__LF
DEC X1
JNZ CAL
EXIT:
LEA DX, MSG9
MOV AH, 9
INT 21H
MOV AH, 7
INT 21H
MOV AX, 4C00H
INT 21H ;返回DOS
;---------------------------
CR__LF:
LEA DX, CR_LF
MOV AH, 9
INT 21H
RET
;---------------------------
INPUT:
MOV BL, 10
MOV CX, 0
IN_X:MOV AH, 7
INT 21H
CMP AL, 13
JE IN_END
CMP AL, '0'
JB IN_X
CMP AL, '9'
JA IN_X
MOV DL, AL
MOV AH, 2
INT 21H
MOV AL, DL
SUB AL, 30H
MOV AH, 0
XCHG AX, CX
MUL BL
ADD CX, AX
CMP CH, 0
JNZ IN_END
JMP IN_X
IN_END:
RET
;---------------------------
BIN2BCD:
MOV AX, N2
MOV X + 0, AX
MOV AX, N2 + 2
MOV X + 2, AX
LEA BX, Y + 4
MOV CX, 5
MOV AL, 0
_QL_:
MOV [BX], AL
DEC BX
LOOP _QL_
MOV CX, 32 ;四个字节的二进制数
_L0_:
PUSH CX
LEA BX, X
MOV CX, 4
CLC
_L1_:
MOV AL, [BX]
ADC AL, AL
MOV [BX], AL
INC BX
LOOP _L1_
LEA BX, Y + 4
MOV CX, 5 ;五个字节的十进制数
_L2_:
MOV AL, [BX]
ADC AL, AL
DAA
MOV [BX], AL
DEC BX
LOOP _L2_
POP CX
LOOP _L0_
RET
;---------------------------
DISP:
LEA BX, Y
MOV CX, 5 ;五个字节的十进制数
_L3_:
MOV AL, [BX]
MOV AH, 0
MOV DL, 16
DIV DL
MOV DL, AL
AND DL, 0FH
ADD DL, 30H
MOV AH, 02H
INT 21H
MOV DL, [BX]
AND DL, 0FH
ADD DL, 30H
INT 21H
INC BX
LOOP _L3_
RET
;---------------------------
OUTPUT:
CALL BIN2BCD
CALL DISP
RET
;---------------------------
CC ENDS
END START
;---------------------------
本程序执行后,输入、输出如下:
c:\masm510>mm
Please input n = 50
01: 0000000001
02: 0000000002
03: 0000000003
04: 0000000005
05: 0000000008
06: 0000000013
07: 0000000021
08: 0000000034
09: 0000000055
10: 0000000089
11: 0000000144
12: 0000000233
13: 0000000377
14: 0000000610
15: 0000000987
16: 0000001597
17: 0000002584
18: 0000004181
19: 0000006765
20: 0000010946
21: 0000017711
22: 0000028657
23: 0000046368
24: 0000075025
25: 0000121393
26: 0000196418
27: 0000317811
28: 0000514229
29: 0000832040
30: 0001346269
31: 0002178309
32: 0003524578
33: 0005702887
34: 0009227465
35: 0014930352
36: 0024157817
37: 0039088169
38: 0063245986
39: 0102334155
40: 0165580141
41: 0267914296
42: 0433494437
43: 0701408733
44: 1134903170
45: 1836311903
46: 2971215073
Press any key to continue ...
c:\masm510>
算到第 46 项,就到了 32 位数的极限了。
继续往下算,还可以使用 48 位数、64 位数...。
使用 48 位数计算、输出的程序,可见做而论道前几年写的博文。
http://hi.baidu.com/do_sermon/item/6acb5f305f6efd08ceb9fee5
以前的数字大小,限于常用的 16 位数的范围。
有个题目,要求计算斐波那契数列的前30项:
http://zhidao.baidu.com/question/872588804722307132.html
算到第 25 项,就超出 16 位二进制数了。
再往下计算,需要用到 32 位数的运算方法。
做而论道编写的程序如下:
ASSUME CS:CC, DS:QW
;---------------------------
QW SEGMENT
MSG1 DB 13, 10, 'Please input n = $'
MSG9 DB 13, 10, 'Press any key to continue ... $'
CR_LF DB 13, 10, 36
X1 DW ?
X2 DW ?
X3 DB 0
N1 DW 0, 0
N2 DW 1, 0
X DW ?, ? ;BIN数字
Y DB 0, 0, 0, 0, 0 ;存放BCD码
QW ENDS
;---------------------------
CC SEGMENT
START:
MOV AX, QW
MOV DS, AX
LEA DX, MSG1
MOV AH, 9
INT 21H
CALL INPUT
MOV X1, CX
MOV X2, CX
CALL CR__LF
CAL:
INC X3
CMP X3, 47 ;第47项将溢出
JZ EXIT
MOV AX, N1
MOV DX, N1 + 2
ADD AX, N2
ADC DX, N2 + 2
MOV BX, N2
MOV N1, BX
MOV BX, N2 + 2
MOV N1 + 2, BX
MOV N2, AX
MOV N2 + 2, DX
MOV AX, X2
SUB AX, X1
INC AX
MOV BL, 10
DIV BL
MOV DX, AX
ADD DL, '0'
MOV AH, 2
INT 21H
MOV DL, DH
ADD DL, '0'
INT 21H
MOV DL, ':'
INT 21H
MOV DL, ' '
INT 21H
CALL OUTPUT
CALL CR__LF
DEC X1
JNZ CAL
EXIT:
LEA DX, MSG9
MOV AH, 9
INT 21H
MOV AH, 7
INT 21H
MOV AX, 4C00H
INT 21H ;返回DOS
;---------------------------
CR__LF:
LEA DX, CR_LF
MOV AH, 9
INT 21H
RET
;---------------------------
INPUT:
MOV BL, 10
MOV CX, 0
IN_X:MOV AH, 7
INT 21H
CMP AL, 13
JE IN_END
CMP AL, '0'
JB IN_X
CMP AL, '9'
JA IN_X
MOV DL, AL
MOV AH, 2
INT 21H
MOV AL, DL
SUB AL, 30H
MOV AH, 0
XCHG AX, CX
MUL BL
ADD CX, AX
CMP CH, 0
JNZ IN_END
JMP IN_X
IN_END:
RET
;---------------------------
BIN2BCD:
MOV AX, N2
MOV X + 0, AX
MOV AX, N2 + 2
MOV X + 2, AX
LEA BX, Y + 4
MOV CX, 5
MOV AL, 0
_QL_:
MOV [BX], AL
DEC BX
LOOP _QL_
MOV CX, 32 ;四个字节的二进制数
_L0_:
PUSH CX
LEA BX, X
MOV CX, 4
CLC
_L1_:
MOV AL, [BX]
ADC AL, AL
MOV [BX], AL
INC BX
LOOP _L1_
LEA BX, Y + 4
MOV CX, 5 ;五个字节的十进制数
_L2_:
MOV AL, [BX]
ADC AL, AL
DAA
MOV [BX], AL
DEC BX
LOOP _L2_
POP CX
LOOP _L0_
RET
;---------------------------
DISP:
LEA BX, Y
MOV CX, 5 ;五个字节的十进制数
_L3_:
MOV AL, [BX]
MOV AH, 0
MOV DL, 16
DIV DL
MOV DL, AL
AND DL, 0FH
ADD DL, 30H
MOV AH, 02H
INT 21H
MOV DL, [BX]
AND DL, 0FH
ADD DL, 30H
INT 21H
INC BX
LOOP _L3_
RET
;---------------------------
OUTPUT:
CALL BIN2BCD
CALL DISP
RET
;---------------------------
CC ENDS
END START
;---------------------------
本程序执行后,输入、输出如下:
c:\masm510>mm
Please input n = 50
01: 0000000001
02: 0000000002
03: 0000000003
04: 0000000005
05: 0000000008
06: 0000000013
07: 0000000021
08: 0000000034
09: 0000000055
10: 0000000089
11: 0000000144
12: 0000000233
13: 0000000377
14: 0000000610
15: 0000000987
16: 0000001597
17: 0000002584
18: 0000004181
19: 0000006765
20: 0000010946
21: 0000017711
22: 0000028657
23: 0000046368
24: 0000075025
25: 0000121393
26: 0000196418
27: 0000317811
28: 0000514229
29: 0000832040
30: 0001346269
31: 0002178309
32: 0003524578
33: 0005702887
34: 0009227465
35: 0014930352
36: 0024157817
37: 0039088169
38: 0063245986
39: 0102334155
40: 0165580141
41: 0267914296
42: 0433494437
43: 0701408733
44: 1134903170
45: 1836311903
46: 2971215073
Press any key to continue ...
c:\masm510>
算到第 46 项,就到了 32 位数的极限了。
继续往下算,还可以使用 48 位数、64 位数...。
使用 48 位数计算、输出的程序,可见做而论道前几年写的博文。
相关文章推荐
- 51单片机定时器编程:这么简单的要求,不用大动干戈
- 80x86 汇编语言编程:输出指定行数的星号
- Java并发编程:Callable、Future和FutureTask
- 如何在代码中为组件设置dip,sp值
- 51 汇编编程:8255 驱动矩阵键盘和数码管
- 51单片机汇编编程--16位流水灯收缩点亮
- 51单片机 C 语言编程:单片机定时中断
- 51单片机汇编编程--16位拉幕灯
- C语言编写51单片机程序:键控流水灯
- c++学习之继承篇(多重继承之虚继承)
- 80x86 汇编语言编程:斐波那契数列
- 51单片机 C语言电子琴
- 80x86汇编编程:显示数据区字符串中第一个空格的位置
- 80x86 汇编代码,在屏幕上显示汉字
- 80x86 汇编语言编程:排序与显示
- MyEclipse开发WebService教程
- 51 单片机 C 语言编程:4×4键盘、164 驱动显示、并发音
- 80x86 汇编语言编程:输入数字串,排序、并求最大和最小
- 51 汇编语言编程:外部中断实验
- 80x86 汇编语言编程:判定数据序列的奇偶个数