1.N!的实现
STACK SEGMENT PARA STACK STACK_AREA DW 100H DUP(?) STACK_BTM EQU ($ - STACK_AREA) STACK ENDS DATA SEGMENT PARA N DW 5 DATA ENDS CODE SEGMENT PARA ASSUME DS:DATA,CS:CODE,SS:STACK MAIN PROC FAR MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV AX,STACK_BTM MOV SP,AX ;初始化 MOV AX,N PUSH AX CALL CALCULATE ;参数传递使用堆栈 CALL PRINT ;参数传递使用AX MOV AX,4C00H INT 21H MAIN ENDP CALCULATE PROC ;入口参数在堆栈中,返回值是AX里 PUSH BP ;利用BP寻址,先保存BP MOV BP,SP PUSH DX ;下文中要用到的寄存器事先保存 PUSH BX MOV BX,[BP+4] ;取得参数N CMP BX,0 JNZ LABEL1 MOV AX,1 ;如果N是0那么返回1 JMP LABEL2 LABEL1: PUSH BX ;保存参数N DEC BX PUSH BX CALL CALCULATE POP BX MUL BX ;AX *= BX LABEL2: POP BX POP DX POP BP RET 2 ;递归计算完成后,入口参数也应该消除,因此SP多+2 CALCULATE ENDP PRINT PROC PUSH AX ;保存 PUSH BX PUSH CX PUSH DX MOV BX,10 MOV CX,0 LOOP1: XOR DX,DX DIV BX PUSH DX INC CX CMP AX,0 JZ LOOP2 JMP LOOP1 LOOP2: POP DX OR DL,30H MOV AH,2 INT 21H LOOP LOOP2 POP DX POP CX POP BX POP AX RET PRINT ENDP CODE ENDS END MAIN
N等于五的时候的输出:
在N=3时的堆栈段情况:
2.一个用于进制转换和乘除法的综合程序(用堆栈传递参数)
MY_STACK SEGMENT PARA STACK
STACK_AREA DW 100H DUP(?)
STACK_BTM EQU $ - STACK_AREA
MY_STACK ENDS
MY_DATA SEGMENT
A DW 1234H
B DW 0011H
MY_ENTER DB 0DH,0AH,'$'
MY_DATA ENDS
MY_CODE SEGMENT
ASSUME CS:MY_CODE,DS:MY_DATA,SS:MY_STACK
MAIN PROC FAR
MOV AX,MY_STACK
MOV SS,AX
MOV AX,MY_DATA
MOV DS,AX
MOV SP,STACK_BTM
MOV AX,A
PUSH AX
CALL TO_HEX ;测试16进制转换
MOV DX,'H'
MOV AH,02H
INT 21H
LEA DX,MY_ENTER
MOV AH,09H
INT 21H
MOV AX,B
PUSH AX
CALL TO_DEC ;测试10进制转换
LEA DX,MY_ENTER
MOV AH,09H
INT 21H
MOV AX,A
PUSH AX
MOV AX,B
PUSH AX
CALL MUL_FUNC;乘法测试
LEA DX,MY_ENTER
MOV AH,09H
INT 21H
MOV AX,A
PUSH AX
MOV AX,B
PUSH AX
CALL DIV_FUNC;除法测试
MOV AX,4C00H
INT 21H
MAIN ENDP
TO_HEX PROC NEAR ;默认参数是在堆栈中,长度是一个字
PUSH AX ;保存要用的寄存器
PUSH BX
PUSH CX
PUSH DX
PUSH BP
MOV BP,SP
MOV AX,[BP+12]
XOR CX,CX
MOV BX,16
LOOP_TO_HEX:
MOV DX,0
DIV BX
CMP DX,10
JAE BRANCH1
OR DL,30H
JMP BRANCH2
BRANCH1: ADD DX,57H
BRANCH2: PUSH DX
INC CX
CMP AX,0
JZ PRINT_HEX
JMP LOOP_TO_HEX
PRINT_HEX:
POP DX
MOV AH,02H
INT 21H
LOOP PRINT_HEX
POP BP
POP DX ;恢复
POP CX
POP BX
POP AX
RET 2
TO_HEX ENDP
TO_DEC PROC NEAR ;默认参数是在堆栈中,长度是一个字
PUSH AX ;保存要用的寄存器
PUSH BX
PUSH CX
PUSH DX
PUSH BP
MOV BP,SP
MOV AX,[BP+12]
XOR CX,CX
MOV BX,10
LOOP_TO_DEC:
MOV DX,0
DIV BX
OR DL,30H
PUSH DX
INC CX
CMP AX,0
JZ PRINT_DEC
JMP LOOP_TO_DEC
PRINT_DEC:
POP DX
MOV AH,02H
INT 21H
LOOP PRINT_DEC
POP BP
POP DX ;恢复
POP CX
POP BX
POP AX
RET 2
TO_DEC ENDP
MUL_FUNC PROC NEAR ;默认参数是在堆栈中,长度是两个字
PUSH AX
PUSH BX
PUSH DX
PUSH BP
MOV BP,SP
MOV AX,[BP+12]
MOV BX,[BP+10]
MUL BX
PUSH DX
CALL TO_HEX
PUSH AX
CALL TO_HEX
MOV DX,'H'
MOV AH,02H
INT 21H
POP BP
POP DX
POP BX
POP AX
RET 4
MUL_FUNC ENDP
DIV_FUNC PROC NEAR ;默认参数是在堆栈中,长度是两个字
PUSH AX
PUSH BX
PUSH DX
PUSH BP
MOV BP,SP
MOV AX,[BP+12]
MOV BX,[BP+10]
XOR DX,DX
DIV BX
PUSH DX
CALL TO_HEX
MOV DX,'H'
MOV AH,02H
INT 21H
LEA DX,MY_ENTER
MOV AH,09H
INT 21H
PUSH AX
CALL TO_HEX
MOV DX,'H'
MOV AH,02H
INT 21H
POP BP
POP DX
POP BX
POP AX
RET 4
DIV_FUNC ENDP
MY_CODE ENDS
END MAIN
输出结果:
3.串操作
;程序功能:1.小写到大写转换
; 2.字符串复制
; 3.字符串按照字典序排序(默认为三个长度相同的字符串)
; 4.字符串替换
; 5.IO检测
STACK SEGMENT PARA STACK
STACK_AREA DW 100H DUP(?)
STACK_BTM EQU $ - STACK_AREA
STACK ENDS
DATA SEGMENT
BUFF_DST DB 'TO LOWER:',0DH,0AH,'$'
BUFF_SRC DB 'TO UPPER',0DH,0AH,'$'
COPY_INFO DB 'AFTER COPYING:',0DH,0AH,'$'
COPY_LEN EQU BUFF_SRC - BUFF_DST
COPY_END DW $
BUFF_DEL DB 'FOR DELETING',0DH,0AH,'$'
DEL_INFO DB 'AFRER DELETING:',0DH,0AH,'$'
DEL_WORD DB 'DELETE'
DEL_END DW $
DEL_LEN EQU DEL_END - DEL_WORD
WORD_OLD DB 'ZHANGCHONGZHI'
WORD_NEW DB 'CHONGZHIZHANG'
BUFF_INFO DB 'AFTER REPLACING:',0DH,0AH,'$'
LEN DW WORD_NEW - WORD_OLD
BUFF DB 'FOR REPLACING:',0DH,0AH
DB 'ZHANGCHONGZHI line1: HOW ARE YOU!',0DH,0AH
DB 'ZHANGCHONGZHI line2: WHAT HAPPENED.',0DH,0AH
DB 'ZHANGCHONGZHI line3: 15061153.',0DH,0AH
DB 'ZHANGCHONGZHI IS A GOOD BOY.',0DH,0AH
DB 0DH,0AH
DB '$'
BUFF_LEN EQU $ - BUFF
BUFF_END DW $
BUFF_UP DB 'TO UPPER:',0DH,0AH,'$'
UP_END DW $
UP_INFO DB 'AFTER UPPERING:',0DH,0AH,'$'
UP_LEN EQU UP_END - BUFF_UP
WORD_TITLE DB 'FOR SORTING:.',0DH,0AH,'$'
WORD_INFO DB 'AFTER SORTING:',0DH,0AH,'$'
WORD_TMP DB 'TEMP',0DH,0AH,'$'
WORD1 DB 'ACDC',0DH,0AH,'$'
WORD2 DB 'PEAR',0DH,0AH,'$'
WORD3 DB 'GOOD',0DH,0AH,'$'
C_LINE DB 0DH,0AH,'$'
WORD_LEN DW WORD2 - WORD1
CMP_TITLE DB 'FOR COMPARING:',0DH,0AH,'$'
CMP_INFO DB 'AFTER COMPARING:',0DH,0AH,'$'
CWORD1 DB 'TEER',0DH,0AH,'$'
CWORD2 DB 'TEAR',0DH,0AH,'$'
EQU_INFO DB 'WORD1 IS EQUAL TO WORD2.',0DH,0AH,'$'
W1_INFO DB 'WORD1 IS GREATER THAN WORD2.',0DH,0AH,'$'
W2_INFO DB 'WORD1 IS SMALLER THAN WORD2.',0DH,0AH,'$'
CWORD_LEN DW CWORD2 - CWORD1
IO_INFO DB 0DH,0AH
DB 'FOR IO TESTING',0DH,0AH
DB 'INPUT A STRING:',0DH,0AH,'$'
STR DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK
MAIN PROC FAR
MOV AX,STACK
MOV SS,AX
MOV SP,STACK_BTM
MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV DX,OFFSET BUFF_UP
MOV AH,9
INT 21H
CALL UPPER
MOV DX,OFFSET UP_INFO
MOV AH,9
INT 21H
MOV DX,OFFSET BUFF_UP
MOV AH,9
INT 21H
MOV DX,OFFSET BUFF_DST
MOV AH,9
INT 21H
MOV DX,OFFSET BUFF_SRC
MOV AH,9
INT 21H
CALL COPY
MOV DX,OFFSET COPY_INFO
MOV AH,9
INT 21H
MOV DX,OFFSET BUFF_DST
MOV AH,9
INT 21H
MOV DX,OFFSET BUFF_SRC
MOV AH,9
INT 21H
MOV DX,OFFSET BUFF
MOV AH,9
INT 21H
CALL INQ
MOV DX,OFFSET BUFF_INFO
MOV AH,9
INT 21H
MOV DX,OFFSET BUFF
MOV AH,9
INT 21H
MOV DX,OFFSET WORD_TITLE
MOV AH,9
INT 21H
MOV DX,OFFSET WORD1
MOV AH,9
INT 21H
MOV DX,OFFSET WORD2
MOV AH,9
INT 21H
MOV DX,OFFSET WORD3
MOV AH,9
INT 21H
MOV DX,OFFSET C_LINE
MOV AH,9
INT 21H
CALL SORT
MOV DX,OFFSET WORD_INFO
MOV AH,9
INT 21H
MOV DX,OFFSET WORD1
MOV AH,9
INT 21H
MOV DX,OFFSET WORD2
MOV AH,9
INT 21H
MOV DX,OFFSET WORD3
MOV AH,9
INT 21H
MOV DX,OFFSET CMP_TITLE
MOV AH,9
INT 21H
MOV DX,OFFSET CWORD1
MOV AH,9
INT 21H
MOV DX,OFFSET CWORD2
MOV AH,9
INT 21H
MOV DX,OFFSET CMP_INFO
MOV AH,9
INT 21H
CALL COMP
MOV DX,OFFSET BUFF_DEL
MOV AH,9
INT 21H
MOV DX,OFFSET DEL_INFO
MOV AH,9
INT 21H
CALL DEL
MOV DX,OFFSET BUFF_DEL
MOV AH,9
INT 21H
MOV DX,OFFSET IO_INFO
MOV AH,9
INT 21H
CALL IO
EXIT: MOV AX,4C00H
INT 21H
MAIN ENDP
DEL PROC
PUSH DI
PUSH BX
PUSH SI
PUSH CX
PUSH AX
MOV DI,OFFSET BUFF_DEL
MOV BX,OFFSET DEL_INFO
LP1_D: CMP DI,BX
JZ DELETE_END
MOV SI,OFFSET DEL_WORD
MOV CX,DEL_LEN
PUSH DI
LP2_D: MOV AL,BYTE PTR [SI]
CMP BYTE PTR [DI],AL
JNZ CONTINUE1
INC SI
INC DI
LOOP LP2_D
MOV SI,DI
MOV CX,OFFSET DEL_INFO
SUB CX,DI
POP DI
PUSH DI
CLD
REP MOVSB
CONTINUE1: POP DI
CONTINUE2: INC DI
JMP LP1_D
DELETE_END: POP AX
POP CX
POP SI
POP BX
POP DI
RET
DEL ENDP
UPPER PROC
PUSH SI
PUSH DI
PUSH CX
PUSH AX
PUSH ES
PUSH DS
POP ES
MOV SI,OFFSET BUFF_UP
MOV DI,SI
MOV CX,UP_LEN
CLD
LP1_U: LODSB
CMP AL,'a'
JB CONTINUE
CMP AL,'z'
JA CONTINUE
SUB AL,20H
CONTINUE: STOSB
LOOP LP1_U
POP ES
POP AX
POP CX
POP DI
POP SI
RET
UPPER ENDP
COPY PROC
PUSH SI
PUSH DI
PUSH CX
PUSH ES
PUSH DS
POP ES
MOV SI,OFFSET BUFF_SRC
MOV DI,OFFSET BUFF_DST
MOV CX,COPY_LEN
CLD
REP MOVSB
POP ES
POP CX
POP DI
POP SI
RET
COPY ENDP
INQ PROC
PUSH DI
PUSH AX
PUSH BX
PUSH SI
MOV DI,OFFSET BUFF
MOV BX,OFFSET BUFF_END
LP1: CMP DI,BX
JZ INQ_END
MOV SI,OFFSET WORD_OLD
MOV CX,LEN
PUSH DI
LP2: MOV AL,BYTE PTR [SI]
CMP BYTE PTR [DI],AL
JNZ BECONTINUE
INC SI
INC DI
LOOP LP2
MOV SI,OFFSET WORD_NEW
POP DI
CALL REPL
JMP INCONTINUE
BECONTINUE: POP DI
INCONTINUE: INC DI
JMP LP1
INQ_END: POP SI
POP BX
POP AX
POP DI
RET
INQ ENDP
REPL PROC
PUSH CX
MOV CX,LEN
CLD
REP MOVSB
POP CX
RET
REPL ENDP
SORT PROC
PUSH CX
PUSH SI
PUSH DI
MOV CX,3
LP_OUT: PUSH CX
MOV SI,OFFSET WORD1
MOV DI,OFFSET WORD2
MOV CX,WORD_LEN
CLD
REPZ CMPSB
JA W1GW2
LP1_S: MOV SI,OFFSET WORD2
MOV DI,OFFSET WORD3
MOV CX,WORD_LEN
CLD
REPZ CMPSB
JA W2GW3
JMP SCONTINUE
W1GW2: MOV SI,OFFSET WORD1
MOV DI,OFFSET WORD_TMP
CALL COPY_S
MOV SI,OFFSET WORD2
MOV DI,OFFSET WORD1
CALL COPY_S
MOV SI,OFFSET WORD_TMP
MOV DI,OFFSET WORD2
CALL COPY_S
JMP LP1_S
W2GW3: MOV SI,OFFSET WORD2
MOV DI,OFFSET WORD_TMP
CALL COPY_S
MOV SI,OFFSET WORD3
MOV DI,OFFSET WORD2
CALL COPY_S
MOV SI,OFFSET WORD_TMP
MOV DI,OFFSET WORD3
CALL COPY_S
SCONTINUE: POP CX
LOOP LP_OUT
POP DI
POP SI
POP CX
RET
SORT ENDP
COPY_S PROC
PUSH CX
MOV CX,WORD_LEN
CLD
REP MOVSB
POP CX
RET
COPY_S ENDP
COMP PROC
MOV SI,OFFSET CWORD1
MOV DI,OFFSET CWORD2
MOV CX,CWORD_LEN
CLD
REPZ CMPSB
JZ EQUAL
JA W1
JB W2
EQUAL: MOV DX,OFFSET EQU_INFO
MOV AH,9
INT 21H
JMP COMP_END
W1: MOV DX,OFFSET W1_INFO
MOV AH,9
INT 21H
JMP COMP_END
W2: MOV DX,OFFSET W2_INFO
MOV AH,9
INT 21H
JMP COMP_END
COMP_END: RET
COMP ENDP
IO PROC
PUSH SI
PUSH AX
PUSH DX
MOV SI,OFFSET STR
LP: MOV AH,1
INT 21H
CMP AL,0DH
JZ NEXT
MOV BYTE PTR [SI],AL
INC SI
JMP LP
NEXT: MOV DL,'$'
MOV BYTE PTR [SI],DL
MOV DX,OFFSET STR
MOV AH,9
INT 21H
POP DX
POP AX
POP SI
RET
IO ENDP
CODE ENDS
END MAIN
结果(部分):
扫描二维码关注公众号,回复:
1071387 查看本文章
;程序功能:在指定位置插入字符串(假定字符串是 15061153 zhangchongzhi),并且打印插入前后的对别
STACK SEGMENT PARA STACK
STACK_AREA DW 100H DUP(?)
STACK_BTM EQU $ - STACK_AREA
STACK ENDS
DATA SEGMENT
INS_WORD DB '15061153 zhangchongzhi' ;插入的字符串
INS_POS DB 'what' ;插入位置
INS_INFO DB 'After inserting ,the result:',0DH,0AH,'$'
INS_LEN EQU INS_POS - INS_WORD
POS_LEN EQU INS_INFO - INS_POS
BUFF_INS DB 'I just want to know what happened yesterday.',0DH,0AH,'$' ;总的字符串
INS_END DW $
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK
MAIN PROC FAR
MOV AX,STACK
MOV SS,AX
MOV SP,STACK_BTM
MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV DX,OFFSET BUFF_INS
MOV AH,9
INT 21H
MOV DX,OFFSET INS_INFO
MOV AH,9
INT 21H
CALL INSERT
MOV DX,OFFSET BUFF_INS
MOV AH,9
INT 21H
EXIT: MOV AX,4C00H
INT 21H
MAIN ENDP
INSERT PROC
PUSH DI
PUSH BX
PUSH SI
PUSH CX
PUSH AX
MOV DI,OFFSET BUFF_INS
MOV BX,OFFSET INS_END
LP1_I: CMP DI,BX
JZ INSERT_END
MOV SI,OFFSET INS_POS
MOV CX,POS_LEN
PUSH DI
LP2_I: MOV AL,BYTE PTR [SI]
CMP BYTE PTR [DI],AL
JNZ CONTINUE1
INC SI
INC DI
LOOP LP2_I
PUSH DI
MOV CX,OFFSET INS_END
SUB CX,DI
MOV SI,OFFSET INS_END
MOV AX,INS_LEN
MOV DI,SI
ADD DI,AX
DEC DI
STD
REP MOVSB
POP DI
MOV SI,OFFSET INS_WORD
MOV CX,INS_LEN
CLD
REP MOVSB
CONTINUE1: POP DI
CONTINUE2: INC DI
JMP LP1_I
INSERT_END: POP AX
POP CX
POP SI
POP BX
POP DI
RET
INSERT ENDP
CODE ENDS
END MAIN
结果: