DATAS SEGMENT
string_1 DB 'Please input a numbers(0-65536):','$'
string_2 DB 'ERROR: OVERFLOW! Please input again:','$'
string_3 DB 'The array you have input is:',0ah,0dh,'$'
string_4 DB 'After Sort the num is:',0ah,0dh,'$'
string_5 DB ' ','$'
DATA DW 10DUP(?)
massege DB 'The sum of the array is: ',0ah,0DH,'$'
DATAS ENDS
说明:
string_1
输入范围提示
string_2
输入错误提示
string_3
输出原数组提示
string_4
输出排序后数组提示
string_5
空格符
DATA
缓冲区数组
2.堆栈段
STACKS SEGMENT
DW 256dup(?)
STACKS ENDS
3.代码段
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
三:模块分解与实现
1. DOS输入10个数字
输入10个无符号数存入缓冲区,并且保证 num<65536
为何输入范围是65536呢 一个字的最大表示范围是 FFFF 其在十进制的表示下为 65535
HEX
FFFF
DEC
65535
BIN
1111 1111 1111 1111
1.1 输入函数子程序
;---------输入函数(单数字输入)------------
Input PROC Near
push AX
push BX
push CX
push DX
;---------输入提示--------------
MOV BX,0
CLC
MOV DX,0;----------输入数字--------------
Lp_0:
MOV AH,1
INT 21H
CMP AL,20H ;回车
JE L_CRLF
;----- x belong to [0,9]----------
SUB AL,30H ; ASCII ->int
JL L_ERROR
CMP AL,9
JG L_ERROR
;------- string ->int-----------
MOV AH,0;将 AL扩展成 AX
XCHG AX, BX ;保护 AX值
MOV CX,10
MUL CX ; bx *=10
ADD AX , BX
JC L_ERROR ; OVERFLOW处理
XCHG AX, BX
JMP Lp_0
L_ERROR:
MOV DX,0
MOV BX,0
CALL CRLF ; 换行
CALL ERROR ; 输出错误提示
JMP Lp_0
L_CRLF:; 以换行作为一个数的结束标志
MOV DX,0
MOV DATA[SI], BX ;
POP DX
POP CX
POP BX
POP AX
RET
Input ENDP
CALL CRLF
MOV DX, OFFSET string_4 ;'After Sort the num is:'
MOV AH,9
INT 21H
MOV CX,10
MOV DI,0
FOR2:
CALL Print
CALL Space
ADD DI ,2
LOOP FOR2
CALL CRLF
输出DATA内的数字,每次输出一个数字然后在输出一个空格
Print函数:
利用DIV函数的特点——每次除10的商放在AX, 余数放入DX
并利用栈的 FILO(First in Last Out)的特点
依旧以1234的例子来看一下是怎么处理的
DATA[Num]
1234
123
12
1
DX
4
3
2
1
Stack(PUSH DX)
4
4,3
4,3,2
4,3,2,1
Print(POP DX)
4
34
234
1234
DATA[Num]/10 的余数存入DX
Print PROC Near
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV CX,0
MOV BX,10
MOV AX, DATA[DI]
LAST:
MOV DX,0
DIV BX ; DIV商放AX,余数放入DX
PUSH DX
INC CX
CMP AX,0
JNZ LAST
AGE:
POP DX
OR DX,30H
MOV AH,2
INT 21H
LOOP AGE
POP DX
POP CX
POP BX
POP AX
RET
Print ENDP
;-------SUM-------------
Get_sum PROC NEAR
PUSH BX
PUSH CX
MOV BX,0
MOV CX ,9
MOV DI,2
LOP1:
MOV BX, DATA[0]
ADD BX, DATA[DI]
MOV DATA[0], BX
ADD DI ,2
LOOP LOP1
POP CX
POP BX
RET
Get_sum ENDP
5.其他函数
;----换行子函数(一个数输入完毕)-------
CRLF PROC Near
push AX
push DX
MOV DL,0ah
MOV AH,2
INT 21H
pop DX
pop AX
RET
CRLF ENDP
;---------空格-----------
Space PROC Near
push AX
push DX
MOV DX, OFFSET string_5 ;' '
MOV AH,9
INT 21H
pop DX
pop AX
RET
Space ENDP
;----------错误提示-------------
ERROR PROC Near
push BX
push DX
MOV DX, OFFSET string_2 ; ERROR: OVERFLOW! Please input again:
MOV AH,9
INT 21H
pop DX
pop BX
RET
ERROR ENDP
四:流程图
1. 总体流程图
2. 子程序流程图
2.1 Input
2.2 Print
2.3 Bubble_Sort
2.4 Get_Sum
五:代码与运行截图
1,完整版代码(在MASM运行通过)
;-----数据段------------
DATAS SEGMENT
string_1 DB 'Please input 10 numbers(0-65536):','$'
string_2 DB 'ERROR: OVERFLOW! Please input again:','$'
string_3 DB 'The array you have input is:',0ah,0dh,'$'
string_4 DB 'After Sort the num is:',0ah,0dh,'$'
string_5 DB ' ','$'
DATA DW 10DUP(?)
massege DB 'The sum of the array is: ',0ah,0DH,'$'
DATAS ENDS
;-----堆栈段------------
STACKS SEGMENT
DW 256dup(?)
STACKS ENDS
;-----代码段------------
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
;-----------程序开始------------
START:
MOV AX,DATAS
MOV DS,AX
MOV SI,0;指针初始化
MOV CX,10;循环次数
;---------Input----------
MOV DX, OFFSET string_1 ;Please input 10numbers(0-65536)
MOV AH,9
INT 21H
Lp:
CALL Input
ADD SI,2
Loop Lp
;--------结束输入,换行---------------
CALL CRLF
MOV DX, OFFSET string_3 ;'The array you have input is:'
MOV AH,9;首地址 DS:DX
INT 21H
;-------输出 ----------------
MOV CX,10
MOV DI,0
Again:
CALL Print
CALL Space
ADD DI ,2
Loop Again
;/******************************/;----------Sort-----------
MOV CX,9
MOV DI,0
FOR1:
CALL Sort
ADD DI,2
LOOP FOR1
CALL CRLF
MOV DX, OFFSET string_4 ;'After Sort the num is:'
MOV AH,9
INT 21H
MOV CX,10
MOV DI,0
FOR2:
CALL Print
CALL Space
ADD DI ,2
LOOP FOR2
CALL CRLF
;-------求和输出---------------------
MOV DX, OFFSET massege;
MOV AH,9
INT 21H
CALL Get_sum
MOV DI,0
CALL Print
EXIT:
MOV AH,4CH
INT 21H
;/************子程序调用****************/;---------输入函数(单数字输入)------------
Input PROC Near
push AX
push BX
push CX
push DX
MOV BX,0
CLC
MOV DX,0;----------输入数字--------------
Lp_0:
MOV AH,1
INT 21H
CMP AL,20H ;空格
JE L_CRLF
;----- x belong to [0,9]----------
SUB AL,30H ; ASCII ->int
JL L_ERROR
CMP AL,9
JG L_ERROR
;------- string ->int-----------
MOV AH,0;将 AL扩展成 AX
XCHG AX, BX ;保护 AX值
MOV CX,10
MUL CX ; bx *=10
ADD AX , BX
JC L_ERROR ; OVERFLOW处理
XCHG AX, BX
JMP Lp_0
L_ERROR:
MOV DX,0
MOV BX,0
CALL CRLF ; 换行
CALL ERROR ; 输出错误提示
JMP Lp_0
L_CRLF:; 以换行作为一个数的结束标志
MOV DX,0
MOV DATA[SI], BX ;
POP DX
POP CX
POP BX
POP AX
RET
Input ENDP
;----换行子函数(一个数输入完毕)-------
CRLF PROC Near
push AX
push DX
MOV DL,0ah
MOV AH,2
INT 21H
pop DX
pop AX
RET
CRLF ENDP
;---------空格-----------
Space PROC Near
push AX
push DX
MOV DX, OFFSET string_5 ;' '
MOV AH,9
INT 21H
pop DX
pop AX
RET
Space ENDP
;----------错误提示-------------
ERROR PROC Near
push BX
push DX
MOV DX, OFFSET string_2 ; ERROR: OVERFLOW! Please input again:
MOV AH,9
INT 21H
pop DX
pop BX
RET
ERROR ENDP
;---------输出函数(单数字输出)-------------
Print PROC Near
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV CX,0
MOV BX,10
MOV AX, DATA[DI]
LAST:
MOV DX,0
DIV BX ; DIV商放AX,余数放入DX
PUSH DX
INC CX
CMP AX,0
JNZ LAST
AGE:
POP DX
OR DX,30H
MOV AH,2
INT 21H
LOOP AGE
POP DX
POP CX
POP BX
POP AX
RET
Print ENDP
;---------SORT---------------------
SORT PROC NEAR
PUSH BX
PUSH DX
MOV SI,DI
LOOP1:
ADD SI,2
MOV BX,DATA[DI]
CMP BX,DATA[SI]
JA CHANGE
JMP NEXT
CHANGE:
MOV DX,DATA[SI]
MOV DATA[DI],DX
MOV DATA[SI],BX
NEXT:
CMP SI,18
JL LOOP1
POP DX
POP BX
RET
SORT ENDP
;-------SUM-------------
Get_sum PROC NEAR
PUSH BX
PUSH CX
MOV BX,0
MOV CX ,9
MOV DI,2
LOP1:
MOV BX, DATA[0]
ADD BX, DATA[DI]
MOV DATA[0], BX
ADD DI ,2
LOOP LOP1
POP CX
POP BX
RET
Get_sum ENDP
CODES ENDS
END START