您的位置:首页 > 编程语言

80x86汇编语言编程:显示杨辉三角形

2016-01-25 12:03 232 查看
看到一个要求输出“杨辉三角形”的题目:

http://zhidao.baidu.com/question/562875215.html

循着给出的链接,找到了百度文库,看了一篇又一篇文章、程序,感觉好像是一个赛着一个的罗嗦。

杨辉三角形,大家都知道,排列形状如下:

1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
… … … … 

各个元素的数值,其排列的规律也很简单,就是上一行的两个相邻元素之和。
按照这个规律,最左边和最右边,还应该各有一列零。当然,零就不显示了。

有人总结的规律,则要高深的多,竟然用上了排列组合的公式,呵呵,这样一来,编程,还能简单得了吗?

计算任意一行,都要把上一行的两个相邻数据,相加、保存。相加的和如果为零,这一行,就计算完毕了。

比如,上一行是 1 2 1,就可以这样算:

1.先用 0 加上 1,这里的 0,就是不显示的《左边元素》,1,就是《右边元素》,即第一个元素。和为 1,应该存入第一个元素的位置。

但是,别忙,这第一个元素,将来还要和它右边的相加,所以要先保存它之后,再存放刚才的和。

2.再用刚保存的 1,当做《左边元素》,用 2 当做《右边元素》,相加为 3;在预先保存了 2 之后,把 3 存入 2 的位置。

3.再用刚保存的 2,当做《左边元素》,用 1 当做《右边元素》,相加为 3;在预先保存了 1 之后,把 3 存入 1 的位置。

4.再用刚保存的 1,当做《左边元素》,用 0 当做《右边元素》,相加为 1;在预先保存了 0 之后,把 1 存入 0 的位置。

5.再用刚保存的 0,当做《左边元素》,其《右边元素》显然也是 0,相加为 0;结束运算。

每一行,都这样计算,算出来的结果,可以当场输出。

想要输出多少行,就这样算多少遍。

经过推算,第 19 行,其最大的元素,就超过了 65535。大于 65535 的数字,用 16 位机来计算,难度就明显加大了。

那么,用 8088 CPU 汇编语言编程来计算杨辉三角形,最大的行数,做而论道认为还是以 18 行为好。

;做而论道用汇编语言编写的输出《杨辉三角形》的程序如下:

;=====================================
DATAS    SEGMENT
  tmp1 DW  1, 20  DUP(0)  ;定义空间用于运行过程中临时存储数据
    
 TITL  DB  0AH, 0DH, '------------------------------------------'
       DB  0AH, 0DH, '          YangHui   triangel'
       DB  0AH, 0DH, '------------------------------------------', 0AH, 0DH

       DB  'Please input the output LineNumber [1~18]: $'

    X  DW  ?
DATAS ENDS
;--------------------------------
CODES   SEGMENT
    ASSUME   CS:CODES, DS:DATAS
START:
    MOV   AX, DATAS
    MOV   DS, AX
;--------------------------------
    LEA   DX, TITL
    MOV   AH, 9
    INT   21H
    CALL  IN_NUM        ;输入行数
;------------------------
    MOV   CX, X         ;取来刚输入的数字
    CMP   CX, 0
    JZ    EXIT          ;判断是否符合范围要求
    CMP   CX, 18
    JA    EXIT
    CALL  CR_LF         ;回车换行
    CALL  CR_LF
M_LOP:                  ;CX=1~18
    LEA   SI, tmp1
    MOV   BX, 0
    CALL  YangHui       ;输出一行
    CALL  CR_LF
    LOOP  M_LOP         ;循环1~18次
;--------------------------------
EXIT:
    MOV   AH, 4CH
    INT   21H
;=====================================
YangHui:                ;计算杨辉三角形
    MOV   AX, [SI]      ;取出数据
    ADD   AX, BX        ;加上《左边数据》
    MOV   BX, [SI]      ;再次取出数据,当做下次的《左边数据》
    MOV   [SI], AX      ;保存和
    JZ    END_YH        ;为零就停止
    ADD   SI, 2
    CALL  PRINT_AX      ;输出
    CALL  SPACE
    JMP   YangHui       ;循环
END_YH:
    RET      ;一行,计算完毕。 这个算法,是不是很简单 ? 
;=====================================
IN_NUM:                 ;输入数字
    MOV   X,  0         ;先清零
    MOV   CX, 2         ;输入2位
IN_X:
    MOV   AH, 7         ;输入单个字符
    INT   21H
    CMP   AL, 13
    JE    END_IN        ;结束
    CMP   AL, '0'
    JB    IN_X          ;小于'0',不是数字
    CMP   AL, '9'
    JA    IN_X

    MOV   DL, AL
    MOV   AH, 2         ;显示单个字符
    INT   21H
    MOV   AL, DL
   
    SUB   AL, '0'       ;还原为数字
    MOV   AH, 0
    MOV   SI, AX        ;暂存新数据.
;
    MOV   AX, X
    MOV   BX, 10        ;老数据乘以10
    MUL   BX
    ADD   AX, SI        ;加上新数据
    MOV   X,  AX        ;保存
    LOOP  IN_X          ;继续输入
END_IN:
    RET
;=====================================
PRINT_AX:
    PUSH  BX
    PUSH  CX
    PUSH  DX

    MOV   BX, 10
    MOV   CX, 0
P_LOP1:
    MOV   DX, 0
    DIV   BX
    INC   CX
    PUSH  DX
    CMP   AX, 0
    JNZ   P_LOP1
    MOV   AH, 2
P_LOP2:
    POP   DX
    ADD   DL, '0'
    INT   21H
    LOOP  P_LOP2

    POP   DX
    POP   CX
    POP   BX
RET
;=====================================
CR_LF:                  ;显示回车换行
    PUSH  AX
    PUSH  DX
    MOV   AH, 2
    MOV   DL, 13
    INT   21H
    MOV   DL, 10
    INT   21H
    POP   DX
    POP   AX
    RET
;=====================================
SPACE:                  ;显示空格
    PUSH  AX
    PUSH  DX
    MOV   AH, 2
    MOV   DL, ' '
    INT   21H
    POP   DX
    POP   AX
    RET
;=====================================
CODES   ENDS
    END   START

程序执行的结果:

c:\masm510> M1
------------------------------------------

          YangHui   triangel
------------------------------------------
Please input the output LineNumber [1~18]: 18

1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1
1 15 105 455 1365 3003 5005 6435 6435 5005 3003 1365 455 105 15 1
1 16 120 560 1820 4368 8008 11440 12870 11440 8008 4368 1820 560 120 16 1
1 17 136 680 2380 6188 12376 19448 24310 24310 19448 12376 6188 2380 680 136 17 1
1 18 153 816 3060 8568 18564 31824 43758 48620 43758 31824 18564 8568 3060 816 153 18 1

c:\masm510>

不知道能否有人来验算一下这些数据是否正确。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: