汇编实现阶乘

汇编语言实现阶乘

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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值