计算杨辉三角形的前n(n<=10)行,并显示在屏幕上。要求计算及显示
用子程序形式实现。其显示格式为:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
CODE SEGMENT ASSUME CS:CODE,DS:CODE org 100h START: jmp beginmessage db 13,10,9,'Input N(N<=10): $'error db 13,10,9,'Data out of range!$'begin: push cs pop ds mov dx,offset message mov ah,9 int 21h call shur cmp bp,10 jbe goon mov dx,offset error mov ah,9 int 21h jmp exitgoon: mov ax,0e0dh int 10h mov al,0ah int 10hpush bp call yhsjexit: mov ah,0 int 16h mov ah,4ch int 21h shur procpush cxpush bxxor bp,bpmov bx,10mov cx,2input:mov ah,0 ;键盘输入数据int 16hcmp al,0dh ;以回车结束输入jz okcmp al,'0' ;只允许输入0~9jb inputcmp al,'9'ja inputmov ah,0eh ;显示有效输入int 10hsub al,30h ;化ASCII为HEXcbw ;字节扩展为字xchg ax,bpmul bx ;扩大10倍add bp,ax ;加一位loop inputok:nop ;数值结果在BP中;恢复用到的寄存器pop bxpop cxretshur endp; 输出杨辉三角的函数,接受一个栈上的参数N; 输出N阶杨辉三角yhsj: mov bp, sp mov ax, [bp+2] ; 保存N到ax shr ax, 1 ; N = N / 2 push ax mov ax, [bp+2] ; 保存N到ax push ax call C; C(N, N/2)获取最后一行中间的那个值,即最大值 call getdigit ; 计算该最大值的长度,如252则返回3 mov cx, ax ; 保存最大长度到cx,用于事后格式用 xor di, di ; 外层循环计数di,外层循环输出每一行 jmp cp1up1: inc di; 更新dicp1: cmp di, [bp+2] ; 测试循环条件,循环N次 jg done1 mov ax, [bp+2] ; 以下3句计算行前空格数 = (N-i)*cl,cl是最大长度 sub ax, di mul cl call showspace ; 输出行前空格 xor si, si ; 内存循环计数si,内层循环输出一行中的每个数 jmp cp2up2: inc si; 更新dicp2: cmp si, di ; 测试循环条件,循环di次 jg done2 push si push di call C; 获取该行的位于si位置的组合数,调用C(di, si) push ax ; 保存该组合数 call show ; 输出该数 mov ax, cx ;┒以下3句输出数字间间隔空格,个数 = N - 1 sub ax, 1 ;┃ call showspace ;┚ pop ax;┒ call getdigit ;┃获取该组合数长度 mov bx, ax ;┃ mov ax, cx ;┃ sub ax, bx ;┃计算需要填充的空格数 = 最大长度 - 该数长度 + 1 add ax, 1 ;┃本来应该先填充再输出数字间空格,顺序反过来是为了左对齐 call showspace ;┚以上打括号的2段反过来是正常的顺序 jmp up2 ; 更新内层循环done2: ; 内层循环结束 mov ah, 2 ; 以下5句实现换行 mov dl, 13 int 21h mov dl, 10 int 21h jmp up1 ; 更新外层循环done1: ; 外层循环结束 ret 2 ; 释放函数参数使用的栈空间; 求组合数的递归函数,接受栈上的2个参数n, m(n > m); 返回C(n, m),即n选m的个数; 算法是:; { C(n, m) = 1 (n < m 或 m = 0); { C(n, m) = C(n-1, m-1) + C(n-1, m) (n > m); 即某位置组合数等于上一行左右两数之和C: push bp mov bp, sp sub sp, 2 ; 预留一个存储位置 mov bx, [bp+6] ; 保存m到bx cmp bx, [bp+4] ; 如果m > n 返回1 jz L1 cmp bx, 0 ; 如果m = 0 返回1 jz L1 mov ax, [bp+4] ; 保存n到ax dec ax; ax = ax - 1 dec bx; bx = bx - 1 push bx push ax call C; 返回上一行左边的那个数 mov [bp-2], ax ; 保存左肩膀上的数 mov ax, [bp+4] ; 以下5句同理,返回上一行右肩膀上的数 dec ax push [bp+6] push ax call C add ax, [bp-2] ; 和左肩膀上的数相加得出该组合数 jmp L2L1: mov ax, 1L2: mov sp, bp pop bp ret 4 ; ax返回组合数; 递归以10进制输出ax; 方法很简单,就是求出余数,然后ax = ax / 10; ax = 0时退出,开始逆序输出求出的各位余数show: mov bx, 10 cmp ax, 0 jz ok1 div bl push ax and ax, 00ffh call show pop dx mov dl, dh or dl, 30h mov ah, 2 int 21hok1: ret; 获取一个数的长度,ax为参数,如果ax = 252则返回3; ax里是返回值getdigit: mov bx, 10 xor dx, dxnext: cmp ax, 0 jle ok2 div bl and ax, 0ffh inc dx jmp nextok2: mov ax, dx ret; 输出ax个空格,参数ax,无返回值showspace: mov bx, ax mov ah, 2 mov dl, ' 'nexts: cmp bx, 0 jle dones int 21h dec bx jmp nextsdones: ret CODE ENDS END START
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。