实验内容:
程序采用菜单式选择,可接收用户输入的命令(1~5),各命令如下:
按1键完成字符串小写字母变大写字母
用户输入一由英文大小写字母或数字0~9组成的字符串(以回车结束),程序逐个检查字符串中各字符,将原串中小写字母变成大写字母,其它字符不变,并在屏幕上显示。用户按任一键,重做,按ESC键,返回主菜单。
按2键完成找最大值(二选一)
1、接收用户输入的可显示字符串(以回车结束),程序将其中ASCII码值最大的字符显示出来。
2、接收用户输入若干无符号8位数(以空格或逗号为分隔符,以回车结束),程序将其中最大的数显示出来。用户按任一键,重做,按ESC键,返回主菜单。
按3键完成排序(二选一)
1、接收用户输入的可显示字符串,以回车结束。程序按ASCII码值大小由大到小排序并输出显示。
2、接收用户输入若干个有符号8位数(以空格逗号为分隔符,以回车结束)。程序将其中最大的数显示出来。用户按任一键,重做,按ESC键,返回主菜单。
按4键显示时间
首先提示用户对时,即用户输入时,分,秒(以空格或冒号分隔,以回车结束),然后,在屏幕上不断显示时间,格式为:××(时):××(分):××(秒),最好定点显示。用户按任一键,重新对时,按ESC键,返回主菜单。(不做要求)
按5键,结束程序运行,返回系统提示符。
DATAS SEGMENT
MENU DB 0DH, 0AH
DB 'Menu Demo by WJY', 0DH , 0AH
DB '1.Input a string.Then convert the small letter to big letter', 0DH, 0AH
DB '2.Find the character whose ASCII code is biggest', 0DH, 0AH
DB '3.Sort the character by ASCII from big to small', 0DH, 0AH
DB '4.NO COMMAND',0DH, 0AH
DB '5.End the program',0DH, 0AH,'$'
MSG1 DB 0DH, 0AH,'Program1---',0DH, 0AH,0DH, 0AH,'$'
MSG2 DB 0DH, 0AH,'Program2---',0DH, 0AH,0DH, 0AH,'$'
MSG3 DB 0DH, 0AH,'Program3---',0DH, 0AH,0DH, 0AH,'$'
MSG4 DB 0DH, 0AH,'Program4---',0DH, 0AH,0DH, 0AH,'$'
MSG5 DB 0DH, 0AH,'End---',0DH, 0AH,0DH, 0AH,'$'
MSG6 DB 0DH, 0AH,'Input numbei has error,please input 1-5 again---',0DH, 0AH,0DH, 0AH,'$'
PRO_END DB 0DH, 0AH,'Program end,input any botton except ESE to do again---',0DH, 0AH,0DH, 0AH,'$'
TIP DB 0DH, 0AH,'Input a number(1-5)---',0DH, 0AH,0DH, 0AH,'$'
CHANGE_LINE DB 0DH,0DH,'$'
TIP1_1 DB 0DH, 0AH,'Input a string---',0DH, 0AH,'$'
TIP1_2 DB 0DH, 0AH,'After convert:',0DH, 0AH,'$'
TIP2_1 DB 0DH, 0AH,'Input a string---',0DH, 0AH,'$'
TIP2_2 DB 0DH, 0AH,'The biggest ASCII code is:',0DH, 0AH,'$'
TIP3_1 DB 0DH, 0AH,'Input a string---',0DH, 0AH,'$'
TIP3_2 DB 0DH, 0AH,'After sort from big to small:',0DH, 0AH,'$'
STRING1 DB 50
DB ?
DB 50 DUP(?)
STRING2 DB 50
DB ?
DB 50 DUP(?)
STRING3 DB 50
DB ?
DB 50 DUP(?)
DATAS ENDS
STACKS SEGMENT STACK 'STACK'
DW 100 DUP(?)
TOP LABEL WORD
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,STACKS
MOV SS,AX
MOV SP,OFFSET TOP
PUSH DS
SUB AX,AX
PUSH AX ; 初始化堆栈
MOV AX,DATAS
MOV DS,AX
MENULOOP:
MOV DX, OFFSET MENU ;主菜单提示语
MOV AH, 09H
INT 21H
MOV DX, OFFSET TIP ;提示输入1-5
MOV AH, 09H
INT 21H
MOV AH, 01H ;输入一个字符
INT 21H
CMP AL,'1' ;与'1'比较
JNE NOT_1
CALL FUNC1 ;如果相等,则执行子程序1
JMP MENULOOP
NOT_1: ;如果输入不是'1',判断是不是'2'
CMP AL, '2'
JNE NOT_2
CALL FUNC2 ;如果相等,则执行子程序2
JMP MENULOOP
NOT_2: ;如果输入不是'2',判断是不是'3'
CMP AL, '3'
JNE NOT_3
CALL FUNC3 ;如果相等,则执行子程序3
JMP MENULOOP
NOT_3: ;如果输入不是'3',判断是不是'4'
CMP AL, '4'
JNE NOT_4
CALL FUNC4 ;如果相等,则执行子程序4
JMP MENULOOP
NOT_4: ;如果输入不是'4',判断是不是'5'
CMP AL, '5'
JNE NOT_5
CALL FUNC5 ;如果相等,则执行子程序5
JMP MENULOOP
NOT_5: ;如果输入不是'5',提示重新输入1-5
CALL FUNC6
JMP MENULOOP
;Program1------------------------------------------
FUNC1 PROC NEAR
MOV DX, OFFSET MSG1
MOV AH, 09H
INT 21H
MOV DX,OFFSET TIP1_1
MOV AH,9
INT 21H ; 提示输入字符串
MOV DX,OFFSET STRING1
MOV AH,0AH
INT 21H ; 把 STRING1的字符串首地址给 DX,输入一个字符串
MOV CX,0
MOV CL,STRING1[1]
MOV BX,1
LOOP1:
INC BX
MOV AL,STRING1[BX]
CMP AL,61H ;与97比较,小于97都不需要改变
JB NEXT1_1
CMP AL,7AH ;与122比较,大于122都不需要改变
JA NEXT1_1
SUB AL,20H
MOV STRING1[BX],AL ;改变后的数据覆盖原来数据
NEXT1_1:
LOOP LOOP1
INC BX
MOV STRING1[BX],'$' ;作用是输出string,由于这里貌似CL就没有用到
MOV DX,OFFSET CHANGE_LINE
MOV AH,9
INT 21H ; 换行
MOV DX,OFFSET TIP1_2
MOV AH,9
INT 21H ; 输出提示的句子
MOV DX,OFFSET STRING1[2]
MOV AH,9
INT 21H ; 输出改变后的字符串
MOV DX,OFFSET PRO_END ; 输出通用结束提示语
MOV AH,9
INT 21H
MOV AH,01H
INT 21H ; 按任一键,重做,按ESC键,返回主菜单
CMP AL,1BH
JE NEXT1_2
JMP FUNC1 ; 如果是 ESC则不跳转到子程序开头,是则跳转
NEXT1_2:
RET
FUNC1 ENDP
;Program2--------------------------------------
FUNC2 PROC NEAR
MOV DX, OFFSET MSG2
MOV AH, 09H
INT 21H
MOV DX,OFFSET TIP2_1
MOV AH, 9
INT 21H ; 提示输入字符串
MOV DX, OFFSET STRING2
MOV AH, 0AH
INT 21H ; 把 STRING2的字符串首地址给 DX,输入一个字符串
MOV AX, 0
MOV CX, 0
MOV CL, STRING2[1] ;CL的值为实际字符长度
MOV BX, 1
LOOP2:
INC BX
CMP AL, STRING2[BX]
JAE NEXT2_1 ;如果AL>STRING2[BX],则跳转
MOV AL, STRING2[BX] ;如果AL小则将STRING2[BX]赋给AL
NEXT2_1:
LOOP LOOP2
MOV SI, BX ; 把 BX的值放到 SI, 也就是指向回车的位置
MOV BL,AL ; 把 AL 放到 BL,防止中断指令时破坏 AL
MOV DX,OFFSET CHANGE_LINE
MOV AH,9
INT 21H ; 换行
MOV DX,OFFSET TIP2_2
MOV AH,9
INT 21H ; 输出提示的句子
MOV DL,BL
MOV AH,2
INT 21H ; 显示最大 ASCII 的字符
MOV DX,OFFSET PRO_END ; 输出通用结束提示语
MOV AH,9
INT 21H
MOV AH,01H
INT 21H ; 按任一键,重做,按ESC键,返回主菜单
CMP AL,1BH
JE NEXT2_2
JMP FUNC2 ; 如果是 ESC则不跳转到子程序开头,是则跳转
NEXT2_2:
RET
FUNC2 ENDP
;Program3----------------------------------------------
FUNC3 PROC NEAR
MOV DX,OFFSET MSG3
MOV AH,9
INT 21H
MOV DX,OFFSET TIP3_1
MOV AH, 9
INT 21H ; 提示输入字符串
MOV DX,OFFSET STRING3 ; 把 STRING3的字符串首地址给 DX,接收一个字符串
MOV AH,0AH
INT 21H
MOV CX,0
MOV CL,STRING3[1] ; 把字符串里字符个数赋给 CX
DEC CX ; 实际比较的次数为 CX-1
CMP CX,0 ;如果只输入一个char就不比较了
JE NO_CHANGE
LOOP3_1: ; 冒泡排序,外层循环
MOV BX,CX ; 小技巧,把 CX的值存到 BX,类似将C++中的i,j,变成同一个变量
MOV SI,2 ; 前面两位分别是最大字节数和实际字节数
LOOP3_2: ;内层循环
MOV AL,STRING3[SI]
CMP AL,STRING3[SI+1]
JA NEXT3_1 ;前一个数大于后一个数则跳转
XCHG AL,STRING3[SI+1]
MOV STRING3[SI],AL ;交换
NEXT3_1:
INC SI
LOOP LOOP3_2 ;LOOP cx自动-1
MOV CX,BX
LOOP LOOP3_1 ;LOOP bx自动-1
NO_CHANGE:
MOV BX,0
MOV BL,STRING3[1];
ADD BL,2 ;前面两位分别是最大字节数和实际字节数
MOV STRING3[BX],'$' ; 将$存入改变后的字符串以作结束标志
MOV DX,OFFSET TIP3_2 ; 输出提示语
MOV AH,9
INT 21H
MOV DX,OFFSET STRING3[2] ; 输出改变后的字符串
MOV AH,9
INT 21H
MOV DX,OFFSET PRO_END ; 输出通用结束提示语
MOV AH,9
INT 21H
MOV AH,01H
INT 21H ; 输入一个字符,实现跳转的判断
CMP AL,1BH
JE NEXT3_2
JMP FUNC3 ; 如果是 ESC则不跳转到子程序开头,是则跳转
NEXT3_2:
RET
FUNC3 ENDP
FUNC4 PROC NEAR
MOV DX, OFFSET MSG4
MOV AH, 09H
INT 21H
RET
FUNC4 ENDP
FUNC5 PROC NEAR
MOV DX, OFFSET MSG5
MOV AH, 09H
INT 21H
JMP EXIT
FUNC5 ENDP
FUNC6 PROC NEAR
MOV DX, OFFSET MSG6
MOV AH, 09H
INT 21H
RET
FUNC6 ENDP
EXIT:
MOV AH,4CH
INT 21H
CODES ENDS
END START