; 实验5_3: 子程序设计三 - 递归阶乘计算 ; 功能:计算N!(通过递归调用实现) ; 入口参数:CX = N(待计算的数) ; 出口参数:AX = N!结果 ; 作者: ; 日期:2026-05-14 DATAS SEGMENT N DW 5 ; 要计算阶乘的数 RESULT DW ? ; 结果存储单元 DATAS ENDS STACKS SEGMENT DW 100H DUP(?) ; 堆栈空间,用于递归调用 STACKS ENDS CODES SEGMENT ASSUME CS:CODES, DS:DATAS, SS:STACKS ; 子程序:FACTORIAL ; 功能:计算N!(递归实现) ; 入口参数:CX = N ; 出口参数:AX = N! ; 说明:递归公式 N! = N * (N-1)!,递归终止条件N<=1 FACTORIAL PROC CMP CX, 1 ; 比较N与1 JBE DONE ; 如果N<=1,跳转到DONE PUSH CX ; 保存当前N值 DEC CX ; 计算N-1 CALL FACTORIAL ; 递归调用,计算(N-1)! POP CX ; 恢复N值 MUL CX ; AX = AX * CX = (N-1)! * N = N! RET DONE: MOV AX, 1 ; 递归终止,返回1(即0!=1或1!=1) RET FACTORIAL ENDP START: MOV AX, DATAS MOV DS, AX MOV CX, N ; 将N送入CX作为入口参数 CALL FACTORIAL ; 调用递归子程序计算阶乘 MOV RESULT, AX ; 保存结果 ; 以下代码用于显示结果(将数字转换为ASCII显示) MOV CX, 0 ; 计数寄存器清零 MOV bx, 10 ; 除数10 DIVIDE_LOOP: XOR DX, DX ; DX清零(32位除法需要) DIV BX ; AX = AX / 10, DX = AX % 10 PUSH DX ; 保存余数(低位先入栈) INC CX ; 计数+1 CMP AX, 0 ; 商是否为0? JNE DIVIDE_LOOP ; 不为0则继续除法 ; 显示结果 DISPLAY_LOOP: POP DX ; 弹出数字 ADD DL, '0' ; 转换为ASCII字符 MOV AH, 02H ; DOS功能:显示字符 INT 21H LOOP DISPLAY_LOOP MOV AH, 4CH ; 程序退出 INT 21H CODES ENDS END START