Assembler - 2 (recursive Caller - factorial)

Keywords: Python ascii REST

This is also the school's curriculum, which deals with the factorials of 0-9.

Why only deal with factorials of 0 -- 9? Ha ha, because in hexadecimal notation, 9! The factorial of can be put down by DX: AX, and it's only the factorial of one digit (single character input). If there's more, we have to think about circular calling. It's a bit troublesome.

In short, to simply do, after all, their level is there, do not dare to be ambitious, so as to avoid trouble. ~o(*  ̄ ▽  ̄ *) o

 

Design idea:

The general design idea is similar to 32-bit unsigned number, the result is stored in memory; the main feature is recursive calling program, that is, the program calls its own program, and finally realizes jump by comparing a bound value. This design is the factorial algorithm in 0-9. There is a design skill: 8! = 40320 (9D80H), 9! = 362880 (58980H). Because of the 16 bit operation MUL of multiplication, the value of AX register is used by default, and the product result is placed in DX: AX. By observing the hexadecimal value of 9!, it can be dropped in DX: AX. Use BX as the multiplier source, increasing from 1. That is, when the input data is 9, BX completes the recursive call from 1 to 9. Because at 8!, the AX is 9D80H, which can be stored. At this time, the BX is 9. After the operation, the value can be sent to DX: AX. If it is decremented from 9 to 1, when BX is 3, the operation result (9X8X7X6X5X4X3=181440) corresponds to 2C4C0H in hexadecimal. At this time, the operation with AX alone will cause distortion. If the operation is to be performed, it is unnecessary to calculate DX first, then AX.

 

Input: enter characters 0-9.

 

Operation (FAC): internal use of hexadecimal operation.

 

ADJUST: since the output is the data after operation in decimal, it needs to be adjusted. The internal implementation is to divide by 10 to get the remainder, and then enter the stack; divide to the last stack, and send it to the memory (only to store the first address of the memory in the highest order, and store in order).

 

OUTPUT: take out the data from the memory, call the 02H function number of 21H, and OUTPUT.

 

Code:

//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        ;Output prompt information
            INT       21H
;INPUT(0-9)
            MOV       AH,01H        ;Input number n
            INT       21H
            SUB       AL,30H      ;ASCII Turn 10 system
            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

It is recommended to use notepad + + or vscode to write and view the code. It feels great!

 

Screenshots:

Note: this output is in decimal, because, the code in addition to 10 out of the rest of the conversion operation! [] ~ ({ ̄)~*

 

 

Well, that's it, no!

Posted by IThinkMyBrainHurts on Mon, 28 Oct 2019 10:59:34 -0700