【ARM汇编数组】输出数组中最大值最小值

在这里插入图片描述

CSDN话题挑战赛第1期
活动详情地址话题PK赛
参赛话题:汇编知识分享
话题描述:我们的计算机知识就像一座金字塔,底层是数学,上面是数字电路,然后是汇编,再往上是操作系统、网络、数据库、高级编程语言、框架等等…我们不可能精通这个金子塔的每一层, 但是想走的更远就必须要了解这个金字塔的底层。因此,学习汇编并不是为了用汇编在应用层设计程序,而是为了深刻理解机器运行程序的机理。就像对于人来说不能没有常识一样,尽管常识不能直接挣钱吃饭,但它影响谈吐,影响你的判断力和决断力,决定着你接受新事物和新知识的程度。汇编就是计算机语言里面的常识和基础。

大家好,我是汤姆凯特。

在这里插入图片描述

每篇前言

☀️作者简介:大家好我是汤姆凯特,大家可以叫我汤姆
🐋个人主页:IM汤姆凯特的CSDN博客
🎁系列专栏:【ARM嵌入式基础】


如何用汇编输出数组中最大值最小值?

前面讲到对数组数据的判断,判断正负数和对数组数据循环求和。这里通过依次比较数据中的数据,选出最大值,为之后用汇编进行冒泡排序提供依据。

一、建立数组循环框架

1.全局变量

  • 全局变量中需要先定义输出语句的格式串
  • 定义一个数组和确定数组的长度
.data 

	 fmt:.asciz " min=%d\n max= %d\n" 
	 array:.word 12,4, -168,122,-33,56,78,99,345, 66,-5 
	.equ nx,( . - array)/4  

2.循环框架构建

  • 先构检出汇编的框架
  • 然后在main中定义一个循环变量r4,再把数组的地址先获取到
  • 构建循环,循环次数由全局变量中的数组长度确定
.text 
.globl main 
 main: 
	 push {lr}         
	 mov r4,#0              
	 ldr r5, =array           
	 ......         
	 b  L1 
loop: 
  	......
	......
	add r4,#1 
L1: cmp r4,#nx   
	blo loop   

二、添加循环核心语句

1.先确定存最小值、最大值的地方

  • 这个程序需要输出两个数据(最小值、最大值)这里我们可以先用寄存器存放
  • 这里先用r6作为最小值的存放,r8作为最大值的存放
  • 由于这两个寄存器要存放数组中的最小值最大值,所以初始化值应该存放数组的首地址
	 ldr r6,[r5] 
	 ldr r8,[r5] 

2.判断并更新r6和r8的数据

找出最小值最大值的思想是:遍历数组中的元素,出现一个数比较两次。以此保证r6中存放的永远是最小的,r8存放的永远是最大的。

  • 一次是跟当前存在r6中的最小值,如果当前r6大于这个数,让这个数替换掉r6,成为新的r6;
  • 另一次是跟当前存在r8中的最大值比较,如果当前r8小于这个数,让这个数替换掉r8,成为新的r8 。
    ldr r7,[r5],#4    //r7依次指向循环中的每一个元素
	cmp  r6,r7        	 
    ldrgt r6,[r5,#-4]   //r5的值并不会改变,将较小的值放到r6
	cmp r8,r7
	ldrlt r8,[r5,#-4]   //r8存放较大的值

3.输出语句

  • 全局变量的格式串中,min在前,max在后,所以把r6的值传给r1,r8的值传给r2 。
	ldr r0, =fmt      
	mov r1,r6  //r6存放min
	mov r2,r8  //r8存放max
	bl printf 

整体代码

//输出数组中最小值最大值
.data 
	 fmt:.asciz " min=%d\n max= %d\n" 
	 array:.word 12,4, -168,122,-33,56,78,99,345, 66,-5 
	.equ nx,( . - array)/4   
.text 
.globl main 
 main: 
	 push {lr}         
	 mov r4,#0              
	 ldr r5, =array           
	 ldr r6,[r5] 
	 ldr r8,[r5]           
	 b  L1 
loop: 
  	
    ldr r7,[r5],#4    //r7依次指向循环中的每一个元素
	cmp  r6,r7        	 
    ldrgt r6,[r5,#-4]   //r5的值并不会改变,将较小的值放到r6
	cmp r8,r7
	ldrlt r8,[r5,#-4]   //r8存放较大的值
	add r4,#1 
L1: cmp r4,#nx   
	blo loop   

	ldr r0, =fmt      
	mov r1,r6  //r6存放min
	mov r2,r8  //r8存放max
	bl printf        
	mov r0, #0       
	pop {lr}  
	mov pc, lr            
.end

运行调试

在这里插入图片描述


总结

  • 找出最小值最大值的思想是:遍历数组中的元素,出现一个数比较两次。以此保证r6中存放的永远是最小的,r8存放的永远是最大的。

  • 用CMP和带后缀指令不断更新最大值最小值。

  • [r5,#-4] 这种寻址方式不改变r5的值,[r5,#-4]!这种方式是前索引改变r5的值。


本期内容就结束了,如果内容有误,麻烦大家评论区指出!
如有疑问可以在评论区留言!
下期预告: ARM汇编判断奇数偶数

CSDN话题挑战赛第1期
活动详情地址话题PK赛

  • 33
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 21
    评论
### 回答1: 以下是 ARM 汇编代码,将一个数组拷贝到另一个数组: ```assembly .syntax unified .data source_array: .word 1, 2, 3, 4, 5 destination_array: .space 20 .text .global main main: ldr r0, =source_array @ Load source array address into r0 ldr r1, =destination_array @ Load destination array address into r1 ldr r2, =5 @ Load array size into r2 @ (assuming 5 elements in array) loop: ldr r3, [r0], #4 @ Load current element from source array @ (increment r0 by 4 bytes) str r3, [r1], #4 @ Store current element into destination array @ (increment r1 by 4 bytes) subs r2, r2, #1 @ Decrement counter bne loop @ Repeat until all elements are copied mov r0, #0 @ Return 0 bx lr ``` 在上面的代码,我们首先定义了 `source_array` 和 `destination_array` 数组,然后在 `main` 函数使用 `ldr` 指令将 `source_array` 和 `destination_array` 的地址分别加载到 `r0` 和 `r1` 寄存器。我们还使用 `ldr` 指令将数组大小(假设为 5)加载到 `r2` 寄存器。 然后,我们使用一个循环来遍历 `source_array` 数组的所有元素,并使用 `ldr` 指令将当前元素加载到 `r3` 寄存器。接下来,我们使用 `str` 指令将当前元素存储到 `destination_array` 数组,并使用 `subs` 指令将计数器 `r2` 减 1。最后,我们使用 `bne` 指令检查计数器是否为零,如果不是则继续循环。 完成循环后,我们使用 `mov` 指令将返回设置为 0,并使用 `bx lr` 指令返回到调用者。 ### 回答2: 汇编语言是一种低级编程语言,它提供了对计算机硬件的直接访问。在ARM汇编,可以使用指令和寄存器来操作数据和内存。为了将一个数组复制到另一个数组,我们可以使用循环和内存访问指令。 首先,需要定义两个数组,一个是源数组,一个是目标数组。 ``` source_array DCD 1, 2, 3, 4, 5 target_array DCD 0, 0, 0, 0, 0 array_size EQU 5 ``` 接下来,我们可以使用循环来遍历源数组,并将复制到目标数组。我们可以使用循环计数器寄存器R1来追踪剩余的元素数量,并使用数组索引寄存器R2和R3分别追踪源数组和目标数组的位置。 ``` MOV R1, array_size ; 设置循环计数器为数组大小 MOV R2, #source_array ; 设置源数组指针 MOV R3, #target_array ; 设置目标数组指针 copy_loop: LDR R0, [R2], #4 ; 从源数组加载一个到寄存器R0,同时更新源数组指针 STR R0, [R3], #4 ; 将寄存器R0的存储到目标数组,同时更新目标数组指针 SUBS R1, R1, #1 ; 循环计数器减1 BNE copy_loop ; 如果循环计数器不为0,则继续循环 ``` 在以上代码,每次循环迭代时,我们先使用LDR指令从源数组加载一个四字节的到寄存器R0。然后使用STR指令将寄存器R0的存储到目标数组。循环计数器R1在每次迭代时递减1,直到达到0,循环终止。 完成以上的代码后,源数组将被成功拷贝到目标数组。请注意,以上代码的源数组和目标数组的大小为5,对于其他大小的数组,需要相应调整数组大小和循环计数器的代码。
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IM汤姆凯特

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值