简介
使用堆栈传参的方式实现字符串增添、删除、大小写转换、查找、替换、比较、排序、输出等功能。
程序运行结果(与跳转表实现相同)
代码
ASSUME CS:CODE1,DS:DATA1,SS:STACK1
STACK1 SEGMENT STACK
STACK_AREA DW 200H DUP(?)
STACK_BTM EQU $-STACK_AREA
STACK1 ENDS
DATA1 SEGMENT
EXPLAIN DB 13,10,"please select function:",13,10
DB "1. append a string to original string",13,10
DB "2.delete string from original stiring",13,10
DB "3.upper",13,10,"4.lower",13,10,"5.find",13,10
DB "6.replace",13,10,"7.compare",13,10,"8.sort",13,10,"9.copy",13,10,"0.output",13,10,"other. quit",13,10,0,'$'
STR_ADD_EXPLAIN DB "please input string you want to append to orignal string ",13,10,0,'$'
STR_DEL_EXPLAIN DB "please input string you want to delete from origin strnig ",13,10,0,'$'
STR_IN_EXPLAIN DB "please input original string",13,10,0,'$'
STR_FIND_EXPLAIN DB "please input string you want to find in original string",13,10,0
STR_FOUND_EXPLAIN DB "position of string you want to find:",0
STR_NOT_FOUND_EXPLAIN DB "the string you want to find not in original string",13,10,0
STR_SRC_EXPLAIN DB "please input string you want to replace for",13,10,0
STR_DST_EXPLAIN DB "please input string you want to replace to",13,10,0
STR_CMP_EXPLAIN DB "pleas input string you want to compare with original string",13,10,0
STR_CMP_SAME_EXPLAIN DB "same",13,10,0
STR_CMP_LESS_EXPLAIN DB "original string is less",13,10,0
STR_CMP_GREATER_EXPLAIN DB "original string is greater",13,10,0
STR_ENTER DB 13,10,0
NUMBER DD 1235H
ASCII DB 20H DUP(0)
FUNC_TABLE DW OUTPUT_ORI,ADD_STR,DEL_STR,UPPER,LOWER,FIND,REPLACE,COMPARE,SORT,SAFE_STRCPY
STR_IN DB 100H DUP(0) ;"HELLO_WORLD" ,0
STR_OUT DB 100H DUP(0) ;
STR_SRC DB 100H DUP(0) ;"L",0
STR_DST DB 100H DUP(0) ;"LL" ,0
DATA1 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
MOV AX,OFFSET STR_IN_EXPLAIN ;read str in
PUSH AX
CALL OUTPUT_STR
MOV AX,OFFSET STR_IN
PUSH AX
CALL INPUT_STR
MAIN_LOOP:
MOV DX,OFFSET EXPLAIN
MOV AH,09H
INT 21H
MOV AH,01H
INT 21H
CMP AL,'0'
JB EXIT
CMP AL,'9'
JA EXIT
SUB AL,'0'
MOV AH,0
MOV BX,AX
SHL BX,1
;MOV SI,OFFSET FUNC_TABLE
;CALL [SI+BX]
JMP SKIP_EXIT
EXIT:
JMP MAIN_EXIT
SKIP_EXIT:
MAIN_OUTPUT_ORI:
CMP AX,0
JNZ MAIN_ADD_STR
CALL OUTPUT_ORI
JMP MAIN_LOOP
MAIN_ADD_STR:
CMP AX,1
JNZ MAIN_DEL_STR
CALL ADD_STR
JMP MAIN_LOOP
MAIN_DEL_STR:
CMP AX,2
JNZ MAIN_UPPER
CALL DEL_STR
JMP MAIN_LOOP
MAIN_UPPER:
CMP AX,3
JNZ MAIN_LOWER
MOV AX,OFFSET STR_IN
PUSH AX
CALL UPPER
JMP MAIN_LOOP
MAIN_LOWER:
CMP AX,4
JNZ MAIN_FIND
MOV AX,OFFSET STR_IN
PUSH AX
CALL LOWER
JMP MAIN_LOOP
MAIN_FIND:
CMP AX,5
JNZ MAIN_REPLACE
CALL FIND
JMP MAIN_LOOP
MAIN_REPLACE:
CMP AX,6
JNZ MAIN_COMP
CALL REPLACE
JMP MAIN_LOOP
MAIN_COMP:
CMP AX,7
JNZ MAIN_SORT
CALL COMPARE
JMP MAIN_LOOP
MAIN_SORT:
CMP AX,8
JNZ MAIN_COPY
MOV AX,OFFSET STR_IN
PUSH AX
CALL SORT
JMP MAIN_LOOP
MAIN_COPY:
CMP AX,9
JNZ MAIN_EXIT
MOV AX,OFFSET STR_OUT
PUSH AX
MOV AX,OFFSET STR_IN
PUSH AX
CALL SAFE_STRCPY
JMP MAIN_LOOP
MAIN_EXIT:
MOV AX,4C00H
INT 21H
MAIN ENDP
OUTPUT_ORI PROC NEAR
PUSH AX
MOV AX,OFFSET STR_IN
PUSH AX
CALL OUTPUT_STR
POP AX
RET
OUTPUT_ORI ENDP
ADD_STR PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX,OFFSET STR_ADD_EXPLAIN
PUSH AX
CALL OUTPUT_STR
MOV AX,OFFSET STR_SRC
PUSH AX
CALL INPUT_STR
MOV AX,OFFSET STR_IN
PUSH AX
CALL STR_LEN
MOV BX,AX
MOV AX,OFFSET STR_IN
ADD AX,BX
;DEC AX
PUSH AX
MOV AX,OFFSET STR_SRC
PUSH AX
CALL SAFE_STRCPY
POP DX
POP CX
POP BX
POP AX
RET
ADD_STR ENDP
DEL_STR PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX,OFFSET STR_DEL_EXPLAIN
PUSH AX
CALL OUTPUT_STR
MOV AX,OFFSET STR_SRC
PUSH AX
CALL INPUT_STR
MOV BX,OFFSET STR_DST
MOV BYTE PTR [BX],0
MOV AX,OFFSET STR_IN
PUSH AX
MOV AX,OFFSET STR_OUT
PUSH AX
MOV AX,OFFSET STR_SRC
PUSH AX
MOV AX,OFFSET STR_DST
PUSH AX
CALL STRRPL
MOV AX,OFFSET STR_IN
PUSH AX
MOV AX,OFFSET STR_OUT
PUSH AX
CALL SAFE_STRCPY
POP DX
POP CX
POP BX
POP AX
RET
DEL_STR ENDP
FIND PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH ES
MOV AX,OFFSET STR_FIND_EXPLAIN
PUSH AX
CALL OUTPUT_STR
MOV AX,OFFSET STR_SRC
PUSH AX
CALL INPUT_STR
MOV AX,OFFSET STR_IN
PUSH AX
CALL STR_LEN
MOV CX,AX
MOV BX,0
FIND_LOOP:
MOV AX,OFFSET STR_SRC
PUSH AX
CALL STR_LEN
PUSH CX
MOV CX,AX
;MOV ES,DS
MOV SI,OFFSET STR_SRC
MOV DI,OFFSET STR_IN
ADD DI,BX
REPZ CMPSB
POP CX
JZ FIND_FOUND
INC BX
LOOP FIND_LOOP
FIND_NOT_FOUND:
MOV AX,OFFSET STR_NOT_FOUND_EXPLAIN
PUSH AX
CALL OUTPUT_STR
JMP FIND_EXIT
FIND_FOUND:
MOV AX,OFFSET STR_FOUND_EXPLAIN
PUSH AX
CALL OUTPUT_STR
;MOV X,OFFSET STR_IN
;SUB DI,BX
PUSH BX
CALL OUTPUT16
FIND_EXIT:
POP ES
POP DX
POP CX
POP BX
POP AX
RET
FIND ENDP
UPPER PROC NEAR ; [sp+2] addr of string
PUSH BP
MOV BP,SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
;MOV SI,OFFSET STR_IN
MOV SI,[BP+4]
UPPER_LOOP:
MOV DL,[SI]
CMP DL,0
JZ END_UPPER_LOOP
CMP DL,'a'
JB SKIP_UPPER
CMP DL,'z'
JA SKIP_UPPER
AND DL,223
MOV [SI],DL
SKIP_UPPER:
INC SI
JMP UPPER_LOOP
END_UPPER_LOOP:
POP SI
POP DX
POP CX
POP BX
POP AX
POP BP
RET 2
UPPER ENDP
LOWER PROC NEAR ; [sp+2] addr of string
PUSH BP
MOV BP,SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
;MOV SI,OFFSET STR_IN
MOV SI,[BP+4]
LOWER_LOOP:
MOV DL,[SI]
CMP DL,0
JZ END_LOWER_LOOP
CMP DL,'A'
JB SKIP_LOWER
CMP DL,'Z'
JA SKIP_LOWER
OR DL,32
MOV [SI],DL
SKIP_LOWER:
INC SI
JMP LOWER_LOOP
END_LOWER_LOOP:
POP SI
POP DX
POP CX
POP BX
POP AX
POP BP
RET 2
LOWER ENDP
REPLACE PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
MOV AX,OFFSET STR_SRC_EXPLAIN ;read src str
PUSH AX
CALL OUTPUT_STR
MOV AX,OFFSET STR_SRC
PUSH AX
CALL INPUT_STR
MOV AX,OFFSET STR_DST_EXPLAIN
PUSH AX
CALL OUTPUT_STR
MOV AX,OFFSET STR_DST ;read dst str
PUSH AX
CALL INPUT_STR
MOV AX,OFFSET STR_IN
PUSH AX
MOV AX,OFFSET STR_OUT
PUSH AX
MOV AX,OFFSET STR_SRC
PUSH AX
MOV AX,OFFSET STR_DST
PUSH AX
CALL STRRPL
MOV AX,OFFSET STR_IN
PUSH AX
MOV AX,OFFSET STR_OUT
PUSH AX
CALL SAFE_STRCPY
POP SI
POP DX
POP CX
POP BX
POP AX
RET
REPLACE ENDP
COMPARE PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
MOV AX,OFFSET STR_CMP_EXPLAIN
PUSH AX
CALL OUTPUT_STR
MOV AX,OFFSET STR_SRC
PUSH AX
CALL INPUT_STR
MOV AX,OFFSET STR_SRC
PUSH AX
CALL STR_LEN
MOV CX,AX
;MOV ES,DS
MOV SI,OFFSET STR_IN
MOV DI,OFFSET STR_SRC
;ADD DI,BX
REPZ CMPSB
JE CMP_SAME
JL CMP_LESS
JG CMP_GREATER
CMP_SAME:
MOV AX,OFFSET STR_CMP_SAME_EXPLAIN
PUSH AX
CALL OUTPUT_STR
JMP CMP_EXIT
CMP_LESS:
MOV AX,OFFSET STR_CMP_LESS_EXPLAIN
PUSH AX
CALL OUTPUT_STR
JMP CMP_EXIT
CMP_GREATER:
MOV AX,OFFSET STR_CMP_GREATER_EXPLAIN
PUSH AX
CALL OUTPUT_STR
CMP_EXIT:
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
RET
COMPARE ENDP
SORT PROC NEAR ;[SP+2] address of string
PUSH BP
MOV BP,SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
;MOV AX, OFFSET STR_IN
MOV AX,[BP+4]
PUSH AX
CALL STR_LEN
MOV BX,OFFSET STR_IN
MOV CX,AX
DEC CX
JCXZ SORT_SKIP
SORT_LOOP1:
MOV SI,AX
DEC SI
SORT_LOOP2:
MOV DL,[BX+SI-1]
MOV DH,[BX+SI]
CMP DL,DH
JBE SORT_SKIP_SWAP
XCHG DL,DH
SORT_SKIP_SWAP:
MOV [BX+SI-1],DL
MOV [BX+SI],DH
DEC SI
CMP SI,0
JNZ SORT_LOOP2
LOOP SORT_LOOP1
SORT_SKIP:
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POP BP
RET 2
SORT ENDP
INPUT_STR PROC NEAR ; [SP+2]ADD of DST_STR \n end
PUSH SI
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV SI,SP
MOV SI,SS:[SI+12]
MOV BX,0
INPUT_STR_LOOP:
MOV AH,01H
INT 21H
CMP AL,13 ;\n
JZ END_INPUT_STR_LOOP
MOV [SI+BX],AL
INC BX
JMP INPUT_STR_LOOP
END_INPUT_STR_LOOP:
MOV BYTE PTR [SI+BX],0
POP DX
POP CX
POP BX
POP AX
POP SI
RET 2
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
SAFE_STRCPY PROC NEAR ; [SP+2]SRC_STR [SP+4]DST_STR
PUSH ES
PUSH SI
PUSH DI
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BX,SP
MOV SI,SS:[BX+16]
MOV DI,SS:[BX+18]
MOV BX,-1
LOOP_GET_LEN:
INC BX
MOV AX,[SI+BX]
CMP AX,0
JNE LOOP_GET_LEN
MOV CX,BX
INC CX
MOV AX,DS
MOV ES,AX
CMP SI,DI
JA LOOP_CPY
STD
ADD SI,BX
ADD DI,BX
LOOP_CPY:
MOVSB
LOOP LOOP_CPY
POP DX
POP CX
POP BX
POP AX
POP DI
POP SI
POP ES
RET 4
SAFE_STRCPY ENDP
STR_LEN PROC NEAR ;[SP+2] addr
PUSH BP
MOV BP,SP
PUSH DI
PUSH ES
PUSH BX
PUSH CX
CLD
MOV AL,0
MOV CX, 7FFFH
MOV DI,[BP+4]
MOV BX,DI
;MOV ES,DS
REPNZ SCASB
SUB DI,BX
DEC DI
MOV AX,DI
POP CX
POP BX
POP ES
POP DI
POP BP
RET 2
STR_LEN ENDP
STRRPL PROC NEAR ;[SP+2]STR_DST [SP+4]STR_SRC [SP+6]STR_OUT [SP+8]STR_IN
PUSH BP
PUSH SI
PUSH DI
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BP,SP
ADD BP,14
MOV SI, [BP+4] ;STR_SRC
MOV BX,-1
LOOP_GET_STR_SRC_LEN: ;BP-2
INC BX
MOV AL,[BX+SI]
CMP AL,0
JNZ LOOP_GET_STR_SRC_LEN
PUSH BX
MOV DI, [BP+2];STR_DST
MOV BX,-1
LOOP_GET_STR_DST_LEN: ;BP-4
INC BX
MOV AL,[BX+DI]
CMP AL,0
JNZ LOOP_GET_STR_DST_LEN
PUSH BX
MOV SI, [BP+8] ;STR_IN
MOV DI, [BP+6] ;STR_OUT
LOOP_CREATE_NEW_STR:
MOV BX,0
MOV CX,0
PUSH DI
MOV DI,[BP+4] ;STR_SRC
LOOP_CMP_STR: ; CX:0 is same
MOV AL,[SI+BX]
MOV AH,[DI+BX]
CMP AH,0
JZ LOOP_CMP_STR_END
XOR AL,AH
OR CL,AL
INC BX
JMP LOOP_CMP_STR
LOOP_CMP_STR_END:
POP DI ;STR_OUT
CMP CX,0
JNZ SKIP_RPL
PUSH DI
MOV AX,[BP+2];STR_DST
PUSH AX
CALL SAFE_STRCPY
MOV AX,[BP-16]
ADD SI,AX
MOV AX,[BP-18]
ADD DI,AX
JMP LOOP_CREATE_NEW_STR
SKIP_RPL:
MOV AL,[SI]
MOV [DI],AL
INC SI
INC DI
CMP AL,0
JNZ LOOP_CREATE_NEW_STR
LOOP_CREATE_NEW_STR_END:
POP BX
POP BX
POP DX
POP CX
POP BX
POP AX
POP DI
POP SI
POP BP
RET 8
STRRPL ENDP
OUTPUT16 PROC NEAR ;OUTPUT ONE NUMBER(16) [SP+2] num
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
MOV BX,SP
MOV BX,SS:[BX+12]
MOV CX,4
OUTPUT_LOOP:
MOV DL,BH
SHR DL,1
SHR DL,1
SHR DL,1
SHR DL,1
CMP DL,10
JB OUTPUT_NUM
ADD DL,41H
SUB DL,10
JMP OUTPUT_FIN
OUTPUT_NUM:
ADD DL,30H
OUTPUT_FIN:
MOV AH,02H
INT 21H
SHL BX,1
SHL BX,1
SHL BX,1
SHL BX,1
LOOP OUTPUT_LOOP
POP SI
POP DX
POP CX
POP BX
POP AX
RET 2
OUTPUT16 ENDP
CODE1 ENDS
END MAIN