一、 设计要求

目的:
(1)学习使用汇编语言实现算法设计
(2)熟练掌握单片机外部存储空间的访问方法
内容:
1.用汇编实现冒泡排序算法。
2.在实验三的代码基础上,利用冒泡排序将DEST中数据从小到大重新排序 。
3.将冒泡排序算法写成子程序。
4.在主程序中,通过设置参数,使用同一个子程序实现从大到小,从小到大排序的自由选择。部分参考代码如下:

……
CLR 7AH ; 从小到大排序
ACALL ORDERS ; 冒泡排序子程序
SETB 7AH ; 从大到小排序
ACALL ORDERS ; 冒泡排序子程序
SJMP $
ORDERS:
……
JB 7AH, …….
…….
RET

二、 实验设计

1.整体思路
定义数据存储区域DEST用于存储待排序的数据。
调用WRITE子程序将五个数据写入存储器。
执行冒泡排序算法,首先从外循环开始,每次外循环都会遍历数据并执行内循环,比较并根据排序方式交换相邻的数据。
内循环负责相邻数据的比较和交换。
如果内循环结束,外循环继续,直到所有数据都排好序。
最后程序进入无限循环,等待进一步操作或中断

2.流程图
在这里插入图片描述

3.主要模块设计思路及分析

(1)WRITE子程序:
将五个特定值写入从地址0x2000开始的外部存储器中。它使用该MOV指令将值加载到累加器A中,然后使用MOVX将它们写入指定的外部存储器位置。

(2)ORDERS子程序:
该ORDERS子例程对外部存储器中的一组五个值执行冒泡排序。它使用两个嵌套循环:外循环i和内循环j。由于有五个值需要排序,因此i=4,j=4。DPTR指向外部存储器的起始地址。在循环内部SORT,它将两个值加载到寄存器 R3 和 R4 中,并对它们进行比较以确定是否需要交换它们。排序形式由 7AH 处的位决定。如果设置为1,则代码从大到小排序;否则,它从小到大排序。
当需要交换时调用CHANGE子程序,它交换外部存储器中的两个值并继续排序过程。排序继续进行,直到所有值对都被比较并排序。外层循环结束后,子程序返回。
(3)CHANGE子程序:
交换外部存储器中的两个值
(4)SORT子程序
取两个数并比较大小

三、 实现效果

1、将数据先存入外部起始地址0x2000H
在这里插入图片描述

2、从小到大排序
在这里插入图片描述

3、从大到小排序
在这里插入图片描述

四、总结

1、冒泡排序算法的实现让我更深入地理解了算法的内部工作原理。通过分解问题,逐步编写代码,以及调试,我提高了解决复杂问题的能力。测试的重要性是无法忽视的。我学会了如何通过模拟器或调试工具进行测试,确保每个子程序和代码段的正确性。这种严格的测试方法可以节省大量的调试时间。总的来说,这个实验是一次深刻的学习经历。通过克服挑战,我不仅提高了汇编编程技能,还增加了对嵌入式系统和底层计算机工作原理的了解。我计划继续探索更多的项目,以进一步提高我的编程能力。
2、一开始将所有数据存储在片内,并设想在片内直接进行排序,但是发现片内的数据修改、移动起来较麻烦,于是改成将数据直接存储于片外。
3、错误地设置了地址或指针,导致数据写入错误的位置,或者无法读取所需的数据。使用符号名称或标签,以提高代码的可读性和可维护性。
4、可以进行代码优化。通过减少不必要的指令、减小代码体积,以及使用最佳的寻址模式,改善代码的效率和可读性。尝试将代码分解为更小、可维护的模块,以简化代码的阅读和维护。

附录:

ORG 0000H
LJMP MAIN
ORG 2000H
MAIN:
DEST XDATA 2000H ; 片外存储数据起始地址
ACALL WRITE
CLR 7AH ; 从小到大排序
ACALL ORDERS ; 冒泡排序子程序
SETB 7AH ; 从大到小排序
ACALL ORDERS ; 冒泡排序子程序
SJMP $
WRITE: ; 将五个数据依次写入存储器
MOV A, #78H
MOV DPTR, #2000H
MOVX @DPTR, A
MOV A, #85H
MOV DPTR, #2001H
MOVX @DPTR, A
MOV A, #35H
MOV DPTR, #2002H
MOVX @DPTR, A
MOV A, #19H
MOV DPTR, #2003H
MOVX @DPTR, A
MOV A, #56H
MOV DPTR, #2004H
MOVX @DPTR, A
RET
ORDERS: ; 冒泡排序
MOV R0, #4H ; 内循环次数j,五个数需循环四次
MOV R1, #4H ; 外循环次数i,五个数需循环四次
MOV DPTR, #DEST ; 指针指向DEST首地址
SORT:
MOVX A, @DPTR ; 取左数
MOV R3, A ; 存入R3
INC DPTR ; 指针移向下一个数
MOVX A, @DPTR ; 取右数
MOV R4, A ; 存入R4
SUBB A, R3 ; 相减,比较大小
DEC R0 ; j–
JNB 7AH, XD ; 判断排序方式,从小到大排序
JB 7AH, DX ; 从大到小排序
XD: JC CHANGE ; 判断右数是否大于左数。有进位则跳转至交换程序
LJMP NOCH ; 若是则不交换
DX: JNC CHANGE ; 判断右数是否小于左数。无进位则跳转至交换程序
LJMP NOCH ; 若是则不交换
CHANGE: ; 交换子程序
DEC DPL ; 指针后移一位
MOV A, R4 ; 左右数进行交换
MOVX @DPTR, A
INC DPTR
MOV A, R3
MOVX @DPTR, A
CJNE R0,#0H, SORT ; 若内循环还未结束,返回SORT继续
LJMP OUTER ; 内循环结束,接着下一次外循环
NOCH: CLR C ; 避免上一次两数相减带来的影响
CJNE R0,#0H, SORT ; 若内循环还未结束,返回SORT继续
LJMP OUTER ; 内循环结束,接着下一次外循环
OUTER: DEC R1 ; i–
MOV R0, #4H ; j重新赋值为4
MOV DPTR, #DEST ; 指针指向DEST首地址
CJNE R1,#0H, SORT ; 若外循环还未结束,返回SORT继续下一次
RET
END

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐