微机原理实验报告冒泡排序.docx
《微机原理实验报告冒泡排序.docx》由会员分享,可在线阅读,更多相关《微机原理实验报告冒泡排序.docx(16页珍藏版)》请在冰豆网上搜索。
微机原理实验报告冒泡排序
一、实验目的
(1)学习汇编语•言循环结构语句的特点,重点掌握冒泡排序的方法。
(2)理解并掌握各种指令的功能,编写完整的汇编源程序。
(3)进一步熟悉DEBUG的调试命令,运用DEBUG进行调试汇编语言程序。
二、实验内容及要求
(1)实验内容:
从键盘输入五个有符号数,用冒泡排序法将英按从小到大的顺序排序。
(2)实验要求:
1编制程序,对这组数进行排序并输出原数据及排序后的数据:
2利用DEBUG调试工具,用DO命令,查看排序前后内存数据的变化:
3去掉最大值和最小值,求岀其余值的平均值,输出最大值、最小值和平均值;
4用压栈PUSH和出栈POP指令,将平均值按位逐个输岀;
5将平均值转化为二进制串,并将这组二进制串输岀:
6所有数据输出前要用字符串的输出指令进行输出提示,所有数据结果能淸晰显示。
三、程序流程图
(1)主程序:
MAIN
(2)冒泡排序子程序:
SORT
4.程序清单
NAMEBUBBLE.SORT
DATASEGMENT
ARRAY
DW5DUP(?
)
;输入数据的存储单元
COUNT
DW5
TWO
DW2
FLAG1
DW0
;判断符号标志
FLAG2
DB0
;判断首位是否为零的标志
FAULT
DW-1
;判断出错标志
CR
DBODH,OAH,'
STR1
DBPleaseinput
fivenumbersseperatedwithspaceandfinishedwith
Enter/,'S'
STR2
DB'Theoriginalnumbers/,'$'
STR3
DB'Thesortednumbers:
'
STR4
DB'TheMin:
\,S,
STR5
DB'TheMax:
\,S,
STR6
DB'TheAverage
STR7
DB'Thebinarysystemofthe
average:
','S'
STR8
DB'Inputerror!
Pleaseinput
again!
''$'
DATA
ENDS
CODE
SEGMENT
MAIN
PROC
FAR
ASSUME
CS:
CODE,DS:
DATA,ES:
DATA
START:
PUSH
DS
AND
AX,0
PUSH
AX
MOV
AX,DATA
MOV
DS,AX
LEA
DX,STR1
MOV
AH,09H
;9号DOS功能调用,提示输入数据
INT
21H
CALL
CRLF
;回车换行
REIN:
CALL
INPUT
;调用INPUT子程序,输入原始数据
CMP
AX,FAULT
;判断是否出错,
JE
REIN
;出错则重新输入
LEA
DX,STR2
MOV
AH,09H
;9号DOS功能调用,提示输岀原始数据
INT
21H
CALL
OUTPUT
;调用OUTPUT子程序,输出原始数据
CALL
SORT
;调用SORT子程序,进行冒泡排序
LEA
DX,STR3
MOV
AH,09H
;9号DOS功能调用,提示输出排序后的数据
INT
21H
CALL
OUTPUT
;调用OUTPUT子程序,输岀排序后的数据
AND
SI,0
AND
BX,0
MOV
BX,ARRAY[SI]
;将最小值存入BX
LEA
DX,STR4
MOV
AH,09H
;9号DOS功能调用,提示输出数据的最小值
INT
21H
CALL
ONE
;调用ONE子程序,输出最小值
CALL
CRLF
LEA
DX,STR5
MOV
AH,09H
;9号DOS功能调用,提示输出排序后的最大值
INT
21H
MOV
BX,ARRAY[SI+8]
;将最大值存入BX
CALL
ONE
;调用0“已子程序,输岀最大值
CALL
CRLF
LEA
DX,STR6
MOV
AH,09H
;9号DOS功能调用,提示输岀平均值
INT
21H
AND
DX,0
MOV
AX,ARRAY[SI+2]
;将去掉最大最小值的其余各数之和存入AX
ADD
AX,ARRAY[SI+4]
ADC
AX,ARRAY[SI+6]
MOV
CX,COUNT
;计数器CX二5
DEC
ex
;cx*-cx-i
DEC
ex
DIV
ex
;字除法,余数存入AX
MOV
BX,AX
;将余下各数的平均值存入BX
CALL
ONE
;调用0旺子程序,输出去掉最大最小值的其余数平均值
CALL
CRLF
LEA
DX,STR6
MOV
AH,09H
;9号DOS功能调用,提示输岀平均值的二进制串
MOV
CX,16
;16位二进制串,计数器初始值为16
LL1:
AND
DX,0
DIV
TWO
PUSH
DX
LOOP
LL1
MOV
CX,16
LL2:
POP
DX
ADD
DL,30H
;将。
1.中的数进行ASCII码转换
MOV
AH,2
;2号DOS功能调用,输出字符“0”或“1”
INT
21H
LOOP
LL2
MOV
AH,1CH
INT21H;4C号功能调用,返回DOS
MAINENDP
子程序:
CRLF功能:
回车和换行
CRLF
PROC
LEA
DX,CR
MOV
AH,09H
INT
21H
RET
CRLF
ENDP
子程序:
INPUT
功能:
输入一组数据
INPUT
PROC
MOV
CX,COUNT
;计数器CX二5
AND
SI,0
NEXT1:
CALL
DTB
;调用DTB子程序,将输入转换为二进制数
DEC
ex
;CX-CX-1
CMP
DL,20H
;判断输入字符是否为空格符
JE
STO
CMP
DL,ODH
;判断输入字符是否为换行符
JE
EXIT2
CALL
CRLF
ERROR:
LEA
DX,STR8
MOV
AH,09H
;9号DOS功能调用,提示输入不合法
INT
21H
CALL
CRLF
MOV
AX,FAULT
;以皿中的值作为岀错标志
JMP
EXIT3
STO:
MOV
ARRAY[SI],BX
;是空格符,将BX中的二进制数存入存储单元
ADD
SI,2
JMP
NEXT1
EXIT2:
MOV
ARRAY[SI],BX
;是换行符,将BX中的二进制数存入存储单元
CALL
CRLF
EXIT3:
RET
INPUT
ENDP
精品
子程序:
DTB
功能:
将键盘输入的十进制数转换为二进制数形式存入BX
DTB
PROC
AND
BX,0
AND
FLAG1,0
;符号标志,0为正,1为负
CHAR:
MOV
AH,01H
;1号DOS功能调用,输入一个字符,存入AL
INT
21H
MOV
DL,AL
CMP
AL,2DH
;判断输入字符是否为负号
JNZ
NEXT2
MOV
FLAG1,1
;是负数,将符号标志FLAG1K1
JMP
CHAR
NEXT2:
SUB
AL,30H
;判断输入字符是否在0-9之间
JL
NEXT3
CMP
AL,09H
JG
NEXT3
CBW
XCHG
AX,BX
;输入字符在0-9之间,将BX中的数乘以10
MOV
CX,10
MUL
ex
XCHG
AX,BX
ADD
BX,AX
;将BX中的数与新输入的数相加
JMP
CHAR
NEXT3:
CMP
FLAG1,1
;根据符号标志判断输入是否为负
JNZ
EXIT1
NEG
BX
;对3乂中的数求补
EXIT1:
RET
DTB
ENDP
子程序:
OUTPUT功能:
输岀一组数据
CALL
CRLF
MOV
DI,COUNT
AND
SI,0
MOV
BX,ARRAY[SI]
TEST
BX,8000H
JZ
G02
G01:
OUTPUTPROC
;计数器DI二5
;将存储单元的第一组数据存入BX
;判断正负
MOV
DL,2DH
MOV
AH,02H
;2号DOS功能调用,输岀负号
INT
21H
NEG
BX
G02:
CALL
ONE
;调用ONE子程序,将BX中二进制数转换为十进制数输岀
MOV
DL,20H
MOV
AH,02H
;2号DOS功能调用,输出空格符
INT
21H
ADD
SI,2
;指针指向下一数据
DEC
DI
JNZ
G01
;计数器DI不为零,继续循环
CALL
CRLF
RET
OUTPUT
ENDP
子程序:
ONE
功能:
将BX中的的二进制数转换为十进制数,由髙到低各位依次输岀
ONE
PROC
PUSHBX
PUSHCX
PUSH
DI
MOV
CX,10000
CALL
BTD
MOV
CX,1000
CALL
BTD
MOV
CX,100
CALL
BTD
MOV
CX,10
CALL
BTD
MOV
CX,1
CALL
BTD
ADD
DL,FLAG2
CMP
DL,30H
JNE
QUIT3
MOV
AH,02H
INT
21H
POP
DI
POP
SI
POP
CX
POP
BX
QUIT3:
PUSHSI
;除数存入CX
;与气T的ASCII码比较,判断该数是否为"0〃
;2号DOS功能调用,输出W
ANDFLAG2,0
RET
ONEENDP
;将首位标志FLAG2重新置0
子程序:
BTD
功能:
将BX中的二进制数转换为一个十进制数输岀
BTD
PROC
MOV
AX,BX
AND
DX,0
DIV
CX
;字除法,商值存入AX,余数存入DX
MOV
BX,DX
;余数存入BX
MOV
DL,AL
ADD
DL,30H
;对DL中的数进行ASCII码转换
CMP
FLAG2,0
;判断是否为首位数据
JNE
QUIT1
CMP
DL,30H
;是首位则判断是否为"0"
JE
QUIT2
;是"0"则不输岀
MOV
FLAG2,1
;不是"0"将首位标志置1
QUIT1:
MOV
AH,02H
;2号DOS功能调用,输出一位十进制数
INT
21H
QUIT2:
RET
BTD
ENDP
子程序:
SORT功能:
冒泡排序
SORT
PROC
CLD
MOV
CX,COUNT
;初始化计数器ex
DEC
CX
;CX=4
L001:
MOV
DI,CX
;CX中的数存入DI
AND
SI,0
L002:
MOV
AX,ARRAY[SI]
CMP
AX,ARRAY[SI+2]
;相邻两数进行比较
几
L003
XCHG
AX,ARRAY[SI+2]
;前一数较大则进行数据交换
MOV
ARRAY[SI],AX
L003:
ADD
SI,2
;前一数较小,则进行下一组比较
LOOP
L002
;CX二0,停止内循环
MOVCX,DI
LOOPLOO1
RET
;还原计数器ex的值
;cx=o,停止外循环
SORTENDP
CODEENDS
ENDSTART
五、运行结果
(l)对300,250,280,240,260五个数进行冒泡排序,运行结果如下:
(2)对-1,2,54,-3&43五个数进行冒泡排序,运行结果如下
(1)当输入不合法时,出现错误提示:
(4)当输入数据不足5个时程序自动补0:
六、心得体会
在本次汇编语言程序设计实验中,我们学习了汇编语言的循环结构,并对冒泡排序法进行了汇编程序设汁,我首先编写了对给左数据进行冒泡排序的算法设讣,这有助于我熟悉冒泡排序的逻辑结构,理淸设汁思路。
汇编语言与C语言相似,然而,在设计过程中,我才意识到,要用汇编语言写出完整的算法程序并不是一件简单的事,一个微小的错误就可能导致整个程序无法正常运行。
在编程时,出现了各种各样的错误,如写程序时没有切换成英式标点,16进制数未加
“H”符号,做字除法运算时忘记将DX淸零而导致“DivideOverflow”。
这些错误都在汇编调试过程中得到改正。
在接下来的上机课程中,我们按照老师的要求对改程序进行了进一步设计一一对从键盘输入的数据进行冒泡排序。
这个算法程序较为复杂,为了使程序能够更加简洁明了,我对其进行了模块化设计,将输入、输岀、冒泡排序等功能分离出来,用子程序一一实现。
由于键盘输入的数据并不能简单的从位数来判左输入输出,我设定将Space作为分隔符,而结朿输入时按Enter键。
为了防止无用输入和输出数据时遗漏“0”,引入了首位符号标志来进行判左。
对算法进行模块化设讣使得实现各功能时无需多重循环,原数据和排序后数拯的输出都可由OUTPUT子程序实现,而最大值、最小值和平均值等都可以由0\E子程序实现单个数据的输出,极大的减少了算法的重复。
在这一阶段,我也遇到了一些困难难,例如在输入完数据回车后程序显示输入错误,经过排查才发现在一2号DOS功能调用时,只写了功能号而忘记“INT21H”,导致数据无法正常显示。
还有诸如子程序结束时没加返回指令RET,命剑过程名时与关键字重复,更改过程名后忘记修改跳转指令等等。
在发现错误和改正错误的过程中增强了我对汇编语言的掌握程度,对算法设计有了更深的了解。
接下来,我还对该算法程序进行了进一步优化,包括数据对齐,出错提示和进行有符号数的排序。
为了实现数据对齐,我增加了CRLF子程序,方便实现回车换行功能。
而为了在输入不合法时,进行错误提示,我立义了岀错标志。
该算法可以对-32768—32767之间的整数进行冒泡排序,为了实现这一功能,我使用了符号标志进行判左,1为负数,0为正数。
在上机实验过程中,我对各条语句的含义都有了更深的理解,编写程序和独立解决问题的能力都得到了加强。
与此同时,我也认识到自己还有诸多不足,例如程序设讣不够简洁,修改算法时往往不能前后兼顾,编写程序不够审慎等等,这些都是我在今后的日子里需要进一步学习和掌握的。
如有侵权请联系告知删除,感谢你们的配合!