ARMC语⾔调⽤汇编函数实现冒泡排序
使⽤冒泡排序将指定数组排序后输出
排序函数使⽤汇编语⾔编写,C语⾔调⽤汇编语⾔
在控制台显⽰排序前后的结果
⼀、问题分析
本程序的关键是如何使⽤汇编语⾔实现冒泡排序算法。可以仿照C语⾔的代码流程,分步骤写出汇编的代码。⾸先要写出最内层的代码部分,也就是数据交换的汇编代码,数据交换可以使⽤str数据装载指令实现。之后要考虑内层循环的代码,可以通过cmp指令控制循环次数。最后是编写最外层的循环代码,也是使⽤cmp指令,来控制整个排序的次数。
⼆、代码编写
2.1 C语⾔代码
#include <stdio.h>
extern void sort(char* num, int count);
int main(){
char number[10] = {'a', 'c', 'b', 'e', 'd', 'f', 'h', 'g', 'j', 'i'};
printf("Before: %s\n", number);
sort(number, 10);
printf("After: %s\n", number);
return 0;
}
C语⾔中⽐较重要的是,⾸先要声明外部函数sort,也就是由汇编代码实现的函数。其代码流程为:
初始化1个10字节的char类型的数组
在控制台输出初始化的数据
调⽤汇编函数进⾏排序
显⽰排序后的结果
2.2 汇编代码
area sort, code, readonly
global sort
start
mov r2, #-1    ; r2->i, i=-1
sub r8, r1, #1  ; r1->count
loop
cmp r2, r8    ; 控制外层循环
c语言中文网汇编语言bge stop
add r2,r2, #1  ; i=i+1
mov r3, #-1    ; r3=j, j=-1
loop0
add r3, r3, #1  ; j=j+1
add r4, r3, #1  ; r4=j+1
sub r7, r8, r2  ; 控制内层循环
cmp r3, r7
bge loop
ldrb r5, [r0, r3]  ; r5=a[j]
ldrb r6, [r0, r4]  ; r6=a[j+1]
cmp r5, r6    ; ⽐较 a[j] 和 a[j+1]
blt loop0
swap
strb r5, [r0, r4]  ; 交换 a[j] 和 a[j+1]
strb r6, [r0, r3]
b loop0
stop
end
汇编语⾔代码是仿照的C语⾔的冒泡排序流程实现的,其⼤致流程为:
⾸先初始化R2,R2⽤来控制外层循环的次数。
数组个数由R1传递进来,然后复制到R8中保存
外层LOOP循环开始,⾸先判断以下外层循环次数,如果外层循环结束,就直接跳转⾄STOP结束循环。类似于C语⾔for循环⾥⾯的判断。
如果外层循环未结束,那么外层循环要实现的就是分别初始化外层R2和内层R3的循环次数。
进⼊内层循环,⽤R3表⽰内层循环次数,R4表⽰内层次数加⼀。
判断内层循环是否已经结束,如果应该结束,就跳转⾄外层循环。
内层循环未结束,就继续执⾏,使⽤ldrb指令将内存中的数据装⼊寄存器R5和R6。
使⽤cmp⽐较R5和R6的数值,如果R5<R6就执⾏下⼀轮内层循环,否则就继续执⾏代码,使⽤数据装载指令STRB,交换R5和R6的数据内容。
数据交换完成过后,进⾏下⼀轮内层循环。
结束
三、ADS调试
3.1 运⾏ADS软件,进⼊调试界⾯
⾸先显⽰的是⼀堆汇编代码,直接点击运⾏,让程序停到主函数⼊⼝处。
接下来是初始化数据,单步执⾏即可。
现在程序已经运⾏到了sort函数的代码⾏,step in进⼊该函数。
3.2 汇编函数调试
可以看到,此时R0和R1的数值分别是0x07FFFFF0和0x0000000A。这两个数分别表⽰C语⾔代码中number数组的⾸地址,以及number数组的字符个数。
现在内存⾥的数值如下:
可以看到,现在前三个数是61、63、62,分别对应acb字符。
第⼀轮内层循环,因为61<63,所以就跳转到了第⼆轮内层循环。第⼆轮内层循环是,63>63,所以就会进⼊交换数据的程序⽚段。
经过交换之后,现在内存中的数值已经变成了61、62、63。
下⾯继续单步执⾏,等到第⼀轮所有的内层循环结束之后,数据就变成了下⾯的效果。
可以看到,最⼤的数据6A已经跑到了最⾼的位置0x7FFFFF9。
接下来的循环,因为数据已经拍好了,所以就不会再有数据交换了。如果此时数据还没有排好,之后的每⼀轮循环,都会将最⼤的数据放到⾼的位置,直到循环结束。
3.3 执⾏结果
最后,程序执⾏的结果如下:
汇编函数执⾏成功。