文章目录
一:题目描述二:伪指令的定义1.数据段2.堆栈段3.代码段
三:模块分解与实现1. DOS输入10个数字1.1 输入函数子程序
2.实现冒泡排序3.DOS输出到屏幕4.求累加和5.其他函数
四:流程图1. 总体流程图2. 子程序流程图2.1 Input2.2 Print2.3 Bubble_Sort2.4 Get_Sum
五:代码与运行截图1,完整版代码(在MASM运行通过)2. 正确运行时截图3. 错误输入时截图
一:题目描述
在键盘输入任意10个数
按从小到大排序后,在计算机屏幕上先输出来。要有结果提示(字符串显示)。将10个数做累加,结果在计算机屏幕显示累加和。
二:伪指令的定义
1.数据段
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
10 DUP(?)
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
256 dup(?)
STACKS ENDS
3.代码段
CODES SEGMENT
ASSUME CS
:CODES
,DS
:DATAS
,SS
:STACKS
三:模块分解与实现
1. DOS输入10个数字
输入10个无符号数存入缓冲区,并且保证
n
u
m
<
65536
num < 65536
num<65536
为何输入范围是65536呢 一个字的最大表示范围是
F
F
F
F
FFFF
FFFF 其在十进制的表示下为 65535
HEXFFFF
DEC65535BIN1111 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
解析函数功能:
本质类似于高精度计算,将读入的一个串转成数字存储在DATA数组中
分成三大部分
一: 输入提示
二: 错误判断及提示
三: 转化为数字
L_ERROR 错误处理
L_CRLF 结束处理
我们来举一个
1234
1234
1234 的例子
Register1234
AX1234BX0112123CX10101010
A
X
+
(
B
X
∗
C
X
)
AX + (BX * CX)
AX+(BX∗CX)
最后将结果存储在DATA数组里
2.实现冒泡排序
冒泡排序作为一个简单的排序算法,时间复杂度
O
(
n
2
)
O(n^2)
O(n2) 需要两层循环,为了提高代码的可读性,我们将内层的循环写成一个子程序每次调用
内层循环很简单,每次从头比到尾,遇到比它小的交换就可以了。因为是字操作数,所以循环的下标到18为结束条件。
;---------Bubble_sort
--------------------
Bubble_sort PROC NEAR
PUSH BX
PUSH DX
MOV SI
,DI
LOOP1
:
ADD SI
,2
MOV BX
,DATA
[DI
]
CMP BX
,DATA
[SI
]
JA SWAP
JMP NEXT
SWAP
:
MOV DX
,DATA
[SI
]
MOV DATA
[DI
],DX
MOV DATA
[SI
],BX
NEXT
:
CMP SI
,18
JL LOOP1
POP DX
POP BX
RET
Bubble_sort ENDP
外层调用:每次
D
I
+
2
DI + 2
DI+2
;----------Sort
-----------
MOV CX
, 9
MOV DI
, 0
FOR1
:
CALL Bubble_sort
ADD DI
, 2
LOOP FOR1
3.DOS输出到屏幕
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]1234123121
DX4321Stack(PUSH DX)44,34,3,24,3,2,1Print(POP DX)4342341234
D
A
T
A
[
N
u
m
]
/
10
DATA[Num] / 10
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
4.求累加和
全部累加到
D
A
T
A
[
0
]
DATA[0]
DATA[0] 上直接调用 Print 函数,因为Print函数是针对DATA数组设计的,所以把最后的结果存入DATA数组中不需要额外的输出函数。
;-------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
10 DUP(?)
massege DB
'The sum of the array is: ',0ah
,0DH
,'$'
DATAS ENDS
;-----堆栈段
------------
STACKS SEGMENT
DW
256 dup(?)
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
10 numbers(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
2. 正确运行时截图
3. 错误输入时截图