汇编语言实现打印杨辉三角

    计算杨辉三角形的前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
    
    

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持lingkb。