x86基础实验-字典排序

简介

输入n个字符串,对其进行字典排序并输出。(每个字符串长度最长为216-1,支持跨段。字符串个数n最多为约214个)

程序运行结果
x86基础实验-字典排序_第1张图片
image.png
代码
ASSUME  CS:CODE1,DS:DATA1,SS:STACK1

STACK1  SEGMENT PARA    STACK
STACK_AREA      DW      100H DUP(?)
STACK_BTM       EQU     $-STACK_AREA
STACK1          ENDS

CODE1   SEGMENT

MAIN    PROC    FAR  

        MOV     AX,STACK1
        MOV     SS,AX
        MOV     SP,STACK_BTM
        MOV     AX,DATA1
        MOV     DS,AX
        MOV     ES,AX


        CALL    INPUT

        MOV     AX,OFFSET POINTER
        PUSH    AX
        ADD     AX,4
        PUSH    AX
        CALL    CMP_STR
        PUSH    AX
        MOV     DX,AX

        MOV     AX,OFFSET POINTER
        PUSH    AX
        MOV     AX,POINTER_LEN
        PUSH    AX
        CALL    SORT


        MOV     CX,POINTER_LEN
        MOV     SI,OFFSET POINTER
OUTPUT_SORTED_STR_LOOP:
        PUSH    SI
        CALL    OUTPUT_STR_DD

        ADD     SI,4

        MOV     AX,OFFSET STR_ENTER
        PUSH    AX
        CALL    OUTPUT_STR

        LOOP OUTPUT_SORTED_STR_LOOP
    

        MOV     AX,4C00H
        INT     21H


MAIN    ENDP

GETCHAR PROC    NEAR    ;获得一个内存地址中存储的字节 ;[sp+2] pos [sp+4] pointer [sp+6] segment pointer,return in AX
        PUSH    BX
        PUSH    CX
        PUSH    DX
        PUSH    SI
        PUSH    ES

        MOV     SI,SP

        MOV     BX,SS:[SI+14] ;pointer
        MOV     ES,SS:[SI+16] ;segment
        MOV     CX,SS:[SI+12] ;pos

        MOV     AX,-1
        SUB     AX,BX
        CMP     AX,CX
        JB      GETCHAR_INC_REPOSITION
        ADD     BX,CX
        MOV     AL,ES:[BX]
        JMP     GETCHAR_EXIT

GETCHAR_INC_REPOSITION:
        MOV     DX,ES
        ADD     DX,1000H
        MOV     ES,DX

        SUB     CX,AX
        DEC     CX
        MOV     BX,CX
        MOV     AL,ES:[BX]

GETCHAR_EXIT:
        MOV     AH,0
        POP     ES
        POP     SI
        POP     DX
        POP     CX
        POP     BX
        RET     6

GETCHAR ENDP

SWAP_DD PROC    NEAR; 交换两个内存地址中的内容 [SP+2] addr dd1 [SP+4] addr dd2

        PUSH    SI
        PUSH    DI
        PUSH    AX
        PUSH    BX
        PUSH    CX
        PUSH    DX

        MOV     SI,SP
        MOV     DI,SS:[SI+16]
        MOV     SI,SS:[SI+14]

        MOV     AX,[SI]
        MOV     DX,[SI+2]
        MOV     BX,[DI]
        MOV     CX,[DI+2]

        MOV     [SI],BX
        MOV     [SI+2],CX

        MOV     [DI],AX
        MOV     [DI+2],DX

        POP     DX
        POP     CX
        POP     BX
        POP     AX
        POP     DI
        POP     SI
        RET     4

SWAP_DD ENDP

CMP_STR PROC    NEAR;   比较两字符串 [SP+2] addr dd of str2 [SP+4] addr dd of str1,ret in al

        PUSH    SI
        PUSH    DI
        PUSH    BX
        PUSH    CX
        PUSH    DX

        MOV     SI,SP
        MOV     DI,SS:[SI+12];str2
        MOV     SI,SS:[SI+14];str1
        
        MOV     CX,0 
        MOV     AX,0

LOOP_CMP_STR:
        MOV     AX,[SI]
        PUSH    AX
        MOV     AX,[SI+2]
        PUSH    AX
        PUSH    CX
        CALL    GETCHAR
        MOV     DL,AL

        MOV     AX,[DI]
        PUSH    AX
        MOV     AX,[DI+2]
        PUSH    AX
        PUSH    CX
        CALL    GETCHAR
        MOV     DH,AL

        SUB     AL,DL 

        JNZ     EXIT_CMP_STR

        CMP     DL,0
        JZ      EXIT_CMP_STR

        INC     CX

        JMP     LOOP_CMP_STR

EXIT_CMP_STR:

        POP     DX
        POP     CX
        POP     BX
        POP     DI
        POP     SI

        RET     4
CMP_STR ENDP

SORT    PROC    NEAR    ;字符串排序 [sp+2] len [sp+4] begin pointer

        PUSH    SI
        PUSH    DI
        PUSH    BP 
        PUSH    AX
        PUSH    BX
        PUSH    CX
        PUSH    DX

        MOV     SI,SP
        MOV     BP,SS:[SI+16];len
        MOV     SI,SS:[SI+18];begin pointer
        
        MOV     DX,BP 
        DEC     DX
SORT_LOOP_1:
        MOV     CX,BP
        DEC     CX
SORT_LOOP_2:
        MOV     BX,CX 
        SHL     BX,1 
        SHL     BX,1 

        MOV     AX,SI;[SI+BX-4] 
        ADD     AX,BX
        SUB     AX,4
        PUSH    AX
        ;MOV     AX,[SI+BX]
        ADD     AX,4
        PUSH    AX
        CALL    CMP_STR

        CMP     AL,0
        JG     SORT_SKIP_SWAP
        
        ;MOV     AX,[SI+BX-4]
        MOV     AX,SI
        ADD     AX,BX
        PUSH    AX
        SUB     AX,4
        ;MOV     AX,[SI+BX]
        PUSH    AX
        CALL    SWAP_DD

SORT_SKIP_SWAP:

        LOOP    SORT_LOOP_2

        DEC     DX
        CMP     DX,0
        JNZ     SORT_LOOP_1

END_SORT_LOOP_1:
        POP     DX
        POP     CX
        POP     BX
        POP     AX
        POP     BP
        POP     DI
        POP     SI
        RET     4
SORT    ENDP

INPUT16 PROC    NEAR ; read a number in 16hex,return in ax
        PUSH    BX
        PUSH    CX
        PUSH    DX

        MOV     DX,0
INPUT16_LOOP:
        MOV     AH,01H
        INT     21H
        CMP AL,30H
        JB  INPUT16_NOT_NUM
        CMP AL,39H
        JA  INPUT16_NOT_NUM
        MOV BH,0
        MOV BL,AL
        SUB BX,30H
        JMP INPUT16_RCL

INPUT16_NOT_NUM:
        CMP AL,41H
        JB  INPUT16_NOT_ALP
        CMP AL,46H
        JA  INPUT16_NOT_ALP
        MOV BH,0
        MOV BL,AL
        SUB BX,41H
        ADD BX,10
        JMP INPUT16_RCL

INPUT16_RCL:
        SHL DX,1
        SHL DX,1
        SHL DX,1
        SHL DX,1
        OR  DL,BL
        JMP INPUT16_LOOP

INPUT16_NOT_ALP:
        MOV AX,DX

        POP    DX
        POP    CX
        POP    BX
        RET 

INPUT16 ENDP

INPUT   PROC    NEAR
        
        MOV     AX,OFFSET STR_INPUT_POINTER_LEN_EXPLAIN
        PUSH    AX
        CALL    OUTPUT_STR

        CALL    INPUT16
        MOV     BX,OFFSET POINTER_LEN
        MOV     [BX],AX
        
        MOV     CX,AX

        MOV     DX,DS
        MOV     ES,DX
        MOV     BP,OFFSET CONTENT
        MOV     SI,OFFSET POINTER
INPUT_LOOP:
        MOV     AX,OFFSET STR_INPUT_CONTENT_EXPLAIN
        PUSH    AX
        CALL    OUTPUT_STR

        MOV     [SI],ES
        MOV     [SI+2],BP
        ADD     SI,4
        CALL    INPUT_STR
        LOOP    INPUT_LOOP

        RET

INPUT   ENDP

INPUT_STR   PROC    NEAR    ;\n end  es:Bp
    
    PUSH SI
    PUSH AX
    PUSH BX
    PUSH CX
    PUSH DX

INPUT_STR_LOOP:
    MOV     AH,01H
    INT     21H
    CMP     AL,13   ;\n
    JZ      END_INPUT_STR_LOOP    
    MOV     ES:[BP],AL 
    INC     BP

    CMP     BP,0
    JNZ     INPUT_STR_LOOP

    MOV     DX,ES
    ADD     DX,1000H
    MOV     ES,DX

    JMP     INPUT_STR_LOOP

END_INPUT_STR_LOOP:

    MOV     BYTE PTR ES:[BP],0
    
    INC     BP
    CMP     BP,0
    JNZ     EXIT_INPUT_STR
    MOV     DX,ES
    ADD     DX,1000H
    MOV     ES,DX

EXIT_INPUT_STR:


    POP DX
    POP CX
    POP BX
    POP AX
    POP SI

    RET 

    
INPUT_STR   ENDP
OUTPUT_STR  PROC    NEAR ;OUTPUT a string end with '\0' [SP+2] str
    PUSH    SI
    PUSH    AX
    PUSH    DX

    MOV     SI,SP
    MOV     SI,SS:[SI+8]

    MOV     AH,2H
OUTPUT_STR_LOOP:
    MOV     DL,[SI]
    CMP     DL,0
    JZ      END_OUTPUT_STR_LOOP
    INT     21H
    INC     SI
    JMP     OUTPUT_STR_LOOP

END_OUTPUT_STR_LOOP:    

    POP     DX
    POP     AX
    POP     SI
    RET     2
OUTPUT_STR  ENDP

OUTPUT_STR_DD   PROC    NEAR ;out astring in [[SP+2]]:[[sp+2]+2]
    PUSH    SI
    PUSH    AX
    PUSH    DX
    PUSH    ES

    MOV     SI,SP
    MOV     SI,SS:[SI+10]
    MOV     DX,[SI]
    MOV     AX,[SI+2]
    MOV     SI,0

OUTPUT_STR_DD_LOOP:
    PUSH    DX
    PUSH    AX

    PUSH    DX
    PUSH    AX
    PUSH    SI
    CALL    GETCHAR

    MOV     DL,AL
    CMP     DL,0
    JZ      END_OUTPUT_STR_DD_LOOP
    MOV     AH,02H
    INT     21H
    INC     SI
    POP     AX
    POP     DX
    JMP     OUTPUT_STR_DD_LOOP

END_OUTPUT_STR_DD_LOOP:
    POP     AX
    POP     DX

    POP     ES
    POP     DX 
    POP     AX
    POP     SI
    RET     2

OUTPUT_STR_DD   ENDP

CODE1   ENDS

DATA1   SEGMENT

STR_INPUT_POINTER_LEN_EXPLAIN   DB  "please input number of words(HEX)",13,10,0
STR_INPUT_CONTENT_EXPLAIN       DB  "please input word",13,10,0
STR_ENTER                   DB  13,10,0

POINTER_LEN         DW  100H  ;support at most 100H words
POINTER             DD  100H  DUP(?)
CONTENT             DB  0

DATA1   ENDS

END MAIN

你可能感兴趣的:(x86基础实验-字典排序)