72 lines
2.0 KiB
NASM
72 lines
2.0 KiB
NASM
; 实验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 |