一、题目
汇编程序实验2
二、要求
片内RAM30H开始的32个单元中分布着随机的有符号8位二进制数,按从小到大的顺序进行排序,排序后的数据仍然保存到30H开始的32个单元中(低地址存放小数据)
三、过程及结果记录(截图)
- 在程序存储器中构建一个TABLE,该表格具有32个随机产生的8位二进制数,如:TABLE :DB 1,3,9,2,17,4,11,6
DB 5,20,100,64,21,14,79,35
DB 92,7,91,23,65,16,13,18
DB 18,73,65,101,27,19,62,69
- 利用查表指令“MOVC A,@A+DPTR”分别将表格中的数字读取到30H~4FH单元中。
- 使用“冒泡排序法”将它们排序即可。“冒泡排序法”的基本原理是:
遍历所有32个数据找出其中最大者,并记下最大数据所在存储位置,然后将这个最大数据放置在最后一个单元,同时,将最后一个单元原来的数据保存到这个最大值原来所处的位置,完成第一轮排序。
- 遍历除了最后一个单元以外的前面31个单元的数据并找出其中最大者,并记下其所在位置。遍历完这一遍后将找到的最大数据保存在倒数第二个单元,并将倒数第二个单元原来的数据保存在刚刚找到的那个最大值原来所在的位置处,完成第二轮排序。依次类推,用同样的方法把所有的数据排好序即可。每一轮将会把当前还未排序的最大的数冒出,因此一共需要冒泡31轮。
冒泡排序的实验结果如下:
图1:排序结果
实验整体思路如下:
图2:实验思路
四、实验源程序
ORG 0000H ;在内存的0地址处就强制转到主程序上去,绕过中断程序
AJMP MAIN ;无条件的转移到主程序
ORG 0090H ;定义代码的起始地址,避开中选程序入口
MAIN: MOV SP,#62H ;设置栈指针
MOV R0,#30H ;使寄存器R0指向30H首地址
MOV DPTR,#TABLE ;使DPTR指向表格开头,直接传送地址
MOV R1,#00 ;设置变址寻址的初值为0+DPTR
MOV R2,#20H ;设置循环次数
READ: MOV A,R1
MOVC A,@A+DPTR ; DPTR为基址,A为变址,每循环一次地址+1
MOV @R0,A ;把表格中内容读出到内存
INC R0 ;自增一并指向下一个内存单元
INC DPTR ;自增一并指向下一个内存单元
DJNZ R2,READ ;R2不为零就跳转到读内存语句,共循环32次,将表格全部内容读到内存中
MOV R7,#1FH ;设置外层循环次数为31次
L1: MOV R1,#30H ;让R1指向该存有数据内存的开头
MOV A,R7 ;将A设置初值为31,即内层循环此数为31次,这是因为第一个数要和剩下的所有31个数进行比较
MOV R6,A ;将A的数存入R6中,后面会对A进行操作,所以使用R6控制内部循环次数
L2: MOV A,@R1 ;寄存器间接寻址操作,将R1对应的内存中的内容移入累加器A
MOV R5,A ;寄存器操作,将R1指向的内容读到R5中存放
INC R1 ;自增一
SUBB A, @R1 ;将第n个单元和第n+1个单元的内容相减
JC L3 ;c是借位标志位,若不为0则说明小于,此时跳转到L3。若第n个单元中的数字大于n+1中的数字则继续执行循环
MOV A,R5 ;将原来R1出的数还给A若是n单元中的数字大于n+1单元中的数字,则将两个单元中的数字交换,将较大的数字放入较小的单元
XCH A,@R1 ;执行交换指令,将n+1内存单元中的小数送给n单元,此时小单元中的数先被暂存在A寄存器中。
DEC R1 ;R1减1,使R1指向当前的内存单元
MOV @R1,A ;将暂存在A中的的小数,送给小内存单元。因为交换指令必须有一个A,所以说对两个内存单元进行交换时,要交换两次
INC R1 ;自增一 ,指向下一个内存单元
L3: DJNZ R6,L2 ;控制内层循环,每次将R6减1,不为零继续循环,每个外循环之内都有n次内循环
DJNZ R7,L1 ;控制外层循环,每次将R7减1,不为零继续循环
SJMP $
ORG 30H ;从30H开始的地址开始写入数据
TABLE: DB 1,3,9,2,17,4,11,6 ;DB代表是字节型的数字
DB 5,20,100,64,21,14,79,35
DB 92,7,91,23,65,16,13,18
DB 18,73,65,101,27,19,62,69
END