ARM汇编指令实验

发布时间 2023-10-23 11:37:08作者: silly_fox

题目

地址为0x40008000起始的内存中存放了20个无符号的8位整数,请编写ARM汇编程序实现如下功能:
采用冒泡法将以上内存中的数据按照从小到大的顺序排列。

注意:在验收实验时,需要自己把具体的数据存放在对应地址的内存中,然后对数据排序,最后通过ADS软件的Memory查看最终的排序结果。

代码编写思路

1.使用EQU将标签指向特定地址
2.使用DCB设定一系列的八位数据
	(DCW是设定16位数据,DCD是设定32位数据)
3.将数据存放在0x40008000的起始地址:
	初始化:①R1加载待保存地址
			 ②R2加载数据地址
			 ③计数器R0置0
	开始循环DATA_LOAD:
			①使用LDRB将R2所指地址的值,移向R3寄存器,并将R2自增指向下一位数据
			②使用STRB将R3寄存器的值保存在R1所指地址中,R1自增。
			③计数器R0自增。
			④比较R0与19的大小,如果小于则跳转至DATA_LOAD继续循环。
4.冒泡排序
		①初始化计数器
		②同存放数据一至,遍历20次,在每次遍历中对20个数据进行比较,置换。
		部分指令的解释:
		STRB/LDRB:以8位存/取数据
		BLS:B跳转,LS条件判断,CMP比较后,小于则执行跳转
		STRLSB:CMP比较后,小于则以8位存数据
		BNE:CMP比较后,不等于则跳转
	MOV:将源操作数放入目的操作数
	LDR:将数据读入寄存器

汇编语言代码

DATA_ADDR      EQU     0x40008000		;使用EQU将标签指向特定地址 

                AREA    Exp1,CODE,READONLY	;声明代码段Exp1
                ENTRY						;标识程序入口
                CODE32						;声明32位ARM指令

START           MOV     R0,#0           ;   R0, 数据加载时间计数器
                LDR     R1,=DATA_ADDR   ;   加载地址0x40008000
                LDR     R2,=DATA        ;   R2存放数据
                B       DATA_LOAD		;	跳转到DATA_LOAD程序存放数据

DATA            DCB 100,95,90,85,80,75,70,65,60,55,50,45,40,35,30,25,20,15,10,5

DATA_LOAD       LDRB    R3,[R2],#1      ;   R3存放数据
                STRB    R3,[R1],#1      ;   将数据依次存放到内存中

                ADD     R0,R0,#1        ;   R0充当计数器,每存放一个数据,加一
                CMP     R0,#19          ;   循环19次直到存放完所有的数据
                BLS     DATA_LOAD       ;   如果没存放完则重新跳转,直到数据存放完毕

                MOV     R0,#0           ;   清零计数器R0
LOOP_1                                  ;	开始冒泡排序,外层循环
                LDR     R1,=DATA_ADDR   ;   R1, 加载数据地址
                ADD     R2,R1,#1        ;   R2为存放下一位数据地址
                MOV     R5,#0           ;   R5内存循环计数器

LOOP_2          
                LDRB    R3,[R1]         ;   R3存放第一个数
                LDRB    R4,[R2]         ;   R4存放第二个数
                CMP     R4,R3           ;   比较R3和R4,如果R4(右边的数)小于R3(左边的数),则执行交换
                STRLSB  R3,[R2]         ;   交换R1与R2的数
                STRLSB  R4,[R1]         ;   交换数据
                ADD     R1,R1,#1        ;   R1地址加1,开始比较下一位
                ADD     R2,R2,#1        ;   R2地址加1,开始比较下一位

                ADD     R5,R5,#1        ;   计数器加1
                CMP     R5,#19          ;   循环19次后退出
                BNE     LOOP_2          ;   未完成循环,继续执行内循环

                ADD     R0,R0,#1        ;   计数器加1
                CMP     R0,#19          ;   比较外循环计数器有没有达到19次
                BNE     LOOP_1          ;   未完成19次循环,继续执行外循环

                MOV     R1,#6           ;   排序完成标志,当排序完成时给R1赋值6(可删去这一步)
                END

运行结果

1.存放数据,排序前:

2.排序后

扩展-如何从大到小排序?

将图中标红部分的R3和R4位置交换,则可以实现数据从大到小的排序。

实验结论及分析

此次实验的冒泡排序采用了嵌套循环,将数组中左右的数进行比较,如果左边的数大于右边的数则进行交换。如果要从大到小排序,则与之相反,右边的数大于左边的数就进行交换,因此,在源程序中只改变一步即可实现数据的从大到小排序。