0-9阶乘
DATA SEGMENT
NUM DB ?;定义数字
FACT DB 1H
RES DB 10 DUP ('$')
MSG1 DB 0ah,0bh,"Please input number",0ah,0bh,"$";定义提示字符
MSG2 DB 0ah,0bh,"Result",0ah,0bh,"$";定义字符,显示结果
MSG3 DB 0ah,0bh,"your input is wrong",0ah,0bh,"$";提示错误
DATA ENDS
;----------------------------------------------------------------堆栈段
stacks segment stack
db 256 dup(0)
stacks ends
;----------------------------------------------------------------
CODE SEGMENT
ASSUME DS:DATA,CS:CODE,SS:STACKS
MAIN PROC FAR
START:
MOV AX,DATA
MOV DS,AX
MOV AX,STACKS
MOV SS,AX
;提示信息
LEA DX,MSG1
MOV AH,09H
INT 21H
;输入数字
MOV AH,01H
INT 21H
;判断数字是否合法
CMP AL,'9'
JA ERROR1
CMP AL,'0'
JB ERROR1
CMP AL,'0'
JE SPE
SUB AL,30H
MOV NUM,AL;将数字从ASCII形式转换成BCD形式
MOV AH,0
MOV AL,FACT
MOV CH,0
MOV CL,NUM;用于循环
LABEL1: MUL CX;阶乘计算
LOOP LABEL1
LEA SI,RES
CALL DISP
LEA DX,MSG2
MOV AH,09H
INT 21H
LEA DX,RES
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
ERROR1: MOV AH,09H;提示输入不满足条件
MOV DX,OFFSET MSG3
INT 21H
MOV AH,4CH
INT 21H
SPE: LEA DX,MSG2
MOV AH,09H
INT 21H
MOV RES,31H
LEA DX,RES
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
;显示数字
DISP PROC NEAR;将AX作为结果并打印
MOV CX,0
MOV BX,10
LOOP1: MOV DX,0;余数入栈
DIV BX
ADD DL,30H;将余数从BCD形式保存为ASCII形式
PUSH DX
INC CX
CMP AX,9;没有到最高位则再循环
JG LOOP1;大于转移
ADD AL,30H
MOV [SI],AL
LOOP2: POP AX;余数出栈并保存
INC SI
MOV [SI],AL
LOOP LOOP2
RET
DISP ENDP
CODE ENDS
END START
0-12阶乘
DATA SEGMENT
INPUT DB 6,7 DUP(0)
RES DB 16 DUP ('$')
MSG1 DB 0ah,0bh,"Please input a number",0ah,0bh,"$";定义提示字符
MSG2 DB 0ah,0bh,"Result",0ah,0bh,"$";定义字符,显示结果
MSG3 DB 0ah,0bh,"your input is wrong",0ah,0bh,"$";提示错误
DATA ENDS
;----------------------------------------------------------------堆栈段
STACKS SEGMENT STACK
DB 256 DUP(0)
STACKS ENDS
;----------------------------------------------------------------
CODE SEGMENT
ASSUME DS:DATA,CS:CODE,SS:STACKS
MAIN PROC FAR
START:
MOV AX,DATA
MOV DS,AX
MOV AX,STACKS
MOV SS,AX
LEA DX,MSG1
MOV AH,09H
INT 21H
LEA DX,INPUT
MOV AH,0AH
INT 21H
CALL STR_NUM ;将字符转换成数字
CMP BX,0H
JE SPECIL
XOR DX, DX
MOV AX, 1 ; 从1开始
; for (dx:ax = 1, cx = 2; cx <= 10; cx++)循环进行阶乘操作
MOV CX,2
L1:
CALL FACTORIAL ; 计算阶乘
INC cx
CMP cx, bx
JBE L1 ;CX <= BX循环,即循环次数
; 输出结果
LEA DI,RES
CALL SHOW
LEA DX,MSG2
MOV AH,09H
INT 21H
LEA DX,RES
MOV AH,09H
INT 21H
MOV AX,4C00H
INT 21H
SPECIL: LEA DX,MSG2
MOV AH,09H
INT 21H
MOV RES,31H
LEA DX,RES
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
STR_NUM PROC NEAR
XOR CX,CX
XOR AX,AX
MOV CL,INPUT[1]
MOV SI,2H
SUB INPUT[SI],30H
LOOP_NUM:
CMP CL,2H
JB ONE_
TWO_:MOV AL,INPUT[SI]
ADD AL,9H
INC SI
SUB INPUT[SI],30H
ADD AL,INPUT[SI]
MOV BX,AX
RET
ONE_:MOV AL,INPUT[SI]
MOV BX,AX
RET
STR_NUM ENDP
FACTORIAL PROC NEAR;DX储存高位,AX储存低位,中间通过SI和DI暂时储存高低位
PUSH DX;入栈
;低位乘积储存
MUL CX
MOV SI,DX
MOV DI,AX
;高位乘积储存
POP AX
MUL CX
ADD AX,SI
ADC DX,0
MOV SI,DX
MOV DX,AX
MOV AX,DI
RET
FACTORIAL ENDP
SHOW PROC NEAR ;将AX作为结果并打印
LL1:
;高位
INC CS:COUNTER
XOR DX, DX
MOV AX, DI ; 高位
MOV CX, AX
DIV BX ; 将余数储存DX,商储存在AX
MOV DI, AX ; 储存新的商
MUL BX ; AX * BX -> DX:AX
SUB CX, AX ; 原来的高位减去进行除法后的高位
;低位
MOV DX, CX
MOV AX, SI ; 低位
DIV BX ; DX:AX / BX -> AX REMAINDER DX
OR DL, 30H ; 将余数转换成ASCII
PUSH DX ; 储存余数
MOV SI, AX ; 储存新的低位
OR AX, DI ; 判断是否继续
JNZ LL1 ; 循环
; 第二个循环:出栈显示
MOV DI, CS:TARGET
MOV CX, CS:COUNTER
LL2:
POP AX
MOV [DI], AL
INC DI
LOOP LL2
MOV BYTE PTR [DI], '$'
RET
COUNTER DW 0
TARGET DW 0 MOV CS:TARGET, DI
MOV SI, AX
MOV DI, DX
MOV CS:COUNTER, 0
MOV BX, 10
SHOW ENDP
CODE ENDS
END START