; 求组合数的递归函数,接受栈上的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 START459