汇编 打印杨辉三角 汇编语言实现打印杨辉三角
dididu1515 人气:0计算杨辉三角形的前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 begin message 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 exit goon: mov ax,0e0dh int 10h mov al,0ah int 10h push bp call yhsj exit: mov ah,0 int 16h mov ah,4ch int 21h shur proc push cx push bx xor bp,bp mov bx,10 mov cx,2 input: mov ah,0 ;键盘输入数据 int 16h cmp al,0dh ;以回车结束输入 jz ok cmp al,'0' ;只允许输入0~9 jb input cmp al,'9' ja input mov ah,0eh ;显示有效输入 int 10h sub al,30h ;化ASCII为HEX cbw ;字节扩展为字 xchg ax,bp mul bx ;扩大10倍 add bp,ax ;加一位 loop input ok:nop ;数值结果在BP中 ;恢复用到的寄存器 pop bx pop cx ret shur 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 cp1 up1: inc di; 更新di cp1: 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 cp2 up2: inc si; 更新di cp2: 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 L2 L1: mov ax, 1 L2: 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 21h ok1: ret ; 获取一个数的长度,ax为参数,如果ax = 252则返回3 ; ax里是返回值 getdigit: mov bx, 10 xor dx, dx next: cmp ax, 0 jle ok2 div bl and ax, 0ffh inc dx jmp next ok2: 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 nexts dones: ret CODE ENDS END START
您可能感兴趣的文章:
加载全部内容