• ARM C语言调用汇编函数 实现冒泡排序


    使用冒泡排序将指定数组排序后输出
    排序函数使用汇编语言编写,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
    ", number);
    	sort(number, 10);
    	printf("After: %s
    ", number);
    
    	return 0;
    }

    C语言中比较重要的是,首先要声明外部函数sort,也就是由汇编代码实现的函数。其代码流程为:

    1. 初始化1个10字节的char类型的数组
    2. 在控制台输出初始化的数据
    3. 调用汇编函数进行排序
    4. 显示排序后的结果

    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				; 控制外层循环
    	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语言的冒泡排序流程实现的,其大致流程为:

    1. 首先初始化R2,R2用来控制外层循环的次数。
    2. 数组个数由R1传递进来,然后复制到R8中保存
    3. 外层LOOP循环开始,首先判断以下外层循环次数,如果外层循环结束,就直接跳转至STOP结束循环。类似于C语言for循环里面的判断。
    4. 如果外层循环未结束,那么外层循环要实现的就是分别初始化外层R2和内层R3的循环次数。
    5. 进入内层循环,用R3表示内层循环次数,R4表示内层次数加一。
    6. 判断内层循环是否已经结束,如果应该结束,就跳转至外层循环。
    7. 内层循环未结束,就继续执行,使用ldrb指令将内存中的数据装入寄存器R5和R6。
    8. 使用cmp比较R5和R6的数值,如果R5<R6就执行下一轮内层循环,否则就继续执行代码,使用数据装载指令STRB,交换R5和R6的数据内容。
    9. 数据交换完成过后,进行下一轮内层循环。
    10. 结束

    三、ADS调试

    3.1 运行ADS软件,进入调试界面

    调试1
    首先显示的是一堆汇编代码,直接点击运行,让程序停到主函数入口处。
    汇编2
    接下来是初始化数据,单步执行即可。
    汇编3
    现在程序已经运行到了sort函数的代码行,step in进入该函数。

    3.2 汇编函数调试

    汇编4
    可以看到,此时R0和R1的数值分别是0x07FFFFF0和0x0000000A。这两个数分别表示C语言代码中number数组的首地址,以及number数组的字符个数。
    现在内存里的数值如下:
    内存数据
    可以看到,现在前三个数是61、63、62,分别对应acb字符。
    第一轮内层循环,因为61<63,所以就跳转到了第二轮内层循环。第二轮内层循环是,63>63,所以就会进入交换数据的程序片段。
    数据交换
    经过交换之后,现在内存中的数值已经变成了61、62、63。
    内存数据2
    下面继续单步执行,等到第一轮所有的内层循环结束之后,数据就变成了下面的效果。
    内存数据3
    可以看到,最大的数据6A已经跑到了最高的位置0x7FFFFF9。
    接下来的循环,因为数据已经拍好了,所以就不会再有数据交换了。如果此时数据还没有排好,之后的每一轮循环,都会将最大的数据放到高的位置,直到循环结束。

    3.3 执行结果

    最后,程序执行的结果如下:
    控制台输出
    汇编函数执行成功。

  • 相关阅读:
    【内网渗透】MSF的exploit和pyload的基础使用
    【代码总结】GD库中图片缩印
    【代码总结】GD库中添加图片水印
    如何调度考生的座位
    回溯算法团灭子集、排列、组合问题
    如何去除有序数组的重复元素
    如何寻找缺失的元素
    如何运用贪心思想玩跳跃游戏
    水塘抽样
    如何同时寻找缺失和重复的元素
  • 原文地址:https://www.cnblogs.com/ZHJ0125/p/12904479.html
Copyright © 2020-2023  润新知