汇编程序 - 2 (递归调用程序 -- 阶乘)

Posted andy-lcw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编程序 - 2 (递归调用程序 -- 阶乘)相关的知识,希望对你有一定的参考价值。

这个也是学校的课设,处理的是 0--9 的阶乘。

为什么只处理0--9的阶乘?哈哈,因为在16进制表示下9!的阶乘能被DX:AX放下啊,而且只是一位数(单个字符输入)的阶乘 ?(^∇^*) ,多了就得考虑循环调用啥的了,有些麻烦。

简言之,往简单做,毕竟自己水平在那,不敢好高骛远,免得自找麻烦哈哈。~ o(* ̄▽ ̄*)o

 

设计思路:

总体设计思路和32位无符号数类似,结果存放在内存中;最主要的特点就是递归调用程序,即程序调用自己程序,最后通过比较一个界值来实现跳转。本设计的是0-9内的阶乘算法,有一个设计技巧:已知8!=40320(9D80H),9!=362880(58980H),由于进行乘法的16位运算MUL时,默认使用AX寄存器的值,乘积的结果放在DX:AX中。通过观察9!的16进制值知,在DX:AX中能放下。使用BX作为乘数源,从1往上递增。即当输入数据为9时,BX从1直到9完成递归调用。因为到8!时,AX中为9D80H,能够存放下,此时BX为9,运算后恰好能将值送到DX:AX中。如果从9递减到1的话,当BX为3时,运算结果(9X8X7X6X5X4X3=181440)对应16进制为2C4C0H,此时单用AX进行运算就会造成失真,如果要运算,需要先算DX的,再算AX的,没有必要。

 

输入:输入为0-9的字符。

 

运算(FAC):内部使用16进制进行运算。

 

调整(ADJUST):由于输出为10进制的运算后的数据,所以需要进行调整。内部实现是除10取余数,然后再入栈;除到最后时出栈,送到内存中去(只是为了内存首地址存储的是最高位,且按顺序存储)。

 

输出(OUTPUT):从内存中取出数据,调用21H的02H功能号,进行输出。

 

代码:

//fac.asm
DATA        SEGMENT
            BUF1      DB 0AH,0DH,ENTER NUMBER(0-9):$
            BUF2      DB 0AH,0DH,RESULT IS :$
            RESULT    DB 6 DUP (?)
DATA        ENDS

CODE        SEGMENT
MAIN        PROC    NEAR
            ASSUME     DS:DATA,CS:CODE
START:    
            MOV       AX,DATA
            MOV       DS,AX
            LEA       DX,BUF1
            MOV       AH,09H        ;输出提示信息
            INT       21H
;INPUT(0-9)
            MOV       AH,01H        ;输入数字n
            INT       21H
            SUB       AL,30H      ;ASCII转10进制
            MOV       BL,AL        ;BL->INPUT_NUMBER
            MOV       BH,00H
            MOV       AX,1
            XOR       DX,DX
            MOV        DI,BX
            MOV        BX,1
;FACT
            CALL      FAC
            LEA       SI,RESULT
;ADJUST
            CALL    ADJUST
            INC        SI
            MOV        AL,0FFH
            MOV        [SI],AL
            LEA       DX,BUF2
            MOV       AH,09H
            INT       21H
;OUTPUT
            MOV        SI,0
            CALL    OUTPUT
            MOV       AH,4CH
            INT       21H
MAIN        ENDP

FAC            PROC      NEAR        
            CMP       BX,DI
            JG        END_FAC
            MUL       BX
            INC       BX
            CALL      FAC
END_FAC:     
            RET
FAC            ENDP
            
ADJUST        PROC      NEAR
            MOV      CX,0
            MOV       BX,10
TURN_DEC:
            DIV       BX
            ADD       DL,30H
            PUSH      DX
            INC       CX
            CMP       AX,9
            MOV       DX,0
            JA        TURN_DEC
            ADD       AL,30H
            MOV       [SI],AL
IN_MEMORY:    
            POP       AX
            INC       SI
            MOV       [SI],AL
            LOOP      IN_MEMORY
            RET
ADJUST         ENDP

OUTPUT        PROC    NEAR
            LEA        DI,RESULT
START_OUT:            
            MOV        BL,[DI]
            CMP        BL,0FFH
            JE        END_OUT
            CMP        BL,30H
            JE        OUT_ADJUST
RET_ADJUST:            
            MOV        DL,[DI]
            MOV        AH,02H
            INT        21H
            INC        DI
            MOV        SI,1
            JMP        START_OUT
OUT_ADJUST:
            CMP        SI,0
            JNE        RET_ADJUST
            INC        DI
            MOV        SI,1
            JMP        START_OUT
END_OUT:            
            RET
OUTPUT        ENDP

CODE           ENDS
            END       START

推荐使用notepad++或者vscode,拿来写和查看代码,感觉很棒!!!

 

截图:

说明:这个输出是10进制了,因为,代码中进行了除10取余的转换操作啦![]~( ̄▽ ̄)~*

 

技术图片

 

嗯,就到这了,没啦!!!

 

以上是关于汇编程序 - 2 (递归调用程序 -- 阶乘)的主要内容,如果未能解决你的问题,请参考以下文章

汇编程序 - 2 (递归调用程序 -- 阶乘)

c语言怎么用递归调用函数的方法求n的阶乘?

Pascal算法之回溯及递推详细介绍、

什么是递归函数?请用递归函数实现10的阶乘

算法与程序设计:递归

计算1!+2!+3!...+(n-1)!+n!。设计求解该问题的C语言程序,阶乘的计算使用递归函数实现