彙編程序 - 2 (遞歸調用程序 -- 階乘)

這個也是學校的課設,處理的是 0--9 的階乘。算法

爲何只處理0--9的階乘?哈哈,由於在16進製表示下9!的階乘能被DX:AX放下啊,並且只是一位數(單個字符輸入)的階乘 ♪(^∇^*) ,多了就得考慮循環調用啥的了,有些麻煩。spa

簡言之,往簡單作,畢竟本身水平在那,不敢好高騖遠,省得自找麻煩哈哈。~ o(* ̄▽ ̄*)o設計

 

設計思路:code

整體設計思路和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的,沒有必要。blog

 

輸入:輸入爲0-9的字符。遞歸

 

運算(FAC):內部使用16進制進行運算。內存

 

調整(ADJUST):因爲輸出爲10進制的運算後的數據,因此須要進行調整。內部實現是除10取餘數,而後再入棧;除到最後時出棧,送到內存中去(只是爲了內存首地址存儲的是最高位,且按順序存儲)。asm

 

輸出(OUTPUT):從內存中取出數據,調用21H的02H功能號,進行輸出。class

 

代碼:循環

//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取餘的轉換操做啦![]~( ̄▽ ̄)~*

 

 

嗯,就到這了,沒啦!!!

相關文章
相關標籤/搜索