這個也是學校的課設,處理的是 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取餘的轉換操做啦![]~( ̄▽ ̄)~*
嗯,就到這了,沒啦!!!