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

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

以上是 汇编语言实现打印杨辉三角 的全部内容, 来源链接: utcz.com/z/347872.html

回到顶部