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