简介
输入n个字符串,对其进行字典排序并输出。(每个字符串长度最长为216-1,支持跨段。字符串个数n最多为约214个)
程序运行结果
代码
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