arm汇编语言使用循环实现数组遍历(正序)
参考博主👚👚👚:IM汤姆凯特
对于数组的遍历我们可以发现,最基本的方法就是一直改变偏移指针的指向去内存取值
- 1+1
- 1+1+1
- 1+1+1+1
- …
当我们需要计算的值足够大时,我们就需要使用到循环语句去帮助我们做计算
接下来就跟我一起去学习学习吧!
1.首先我们先回顾一下C语言对数组的遍历代码
- 定义数组
- 求数组长度
- 循环遍历数组,取值打印
#include<stdio.h>
int main(){
int array[]={1,2,3,4,5,6,7,8,9};
int i = 0;
int length = sizeof(array)/sizeof(array[0]);
for(i; i<length;i++){
printf("%5d",array[i]);
}
return 0;
}
2.我们将arm汇编语言的模板敲出来
.data
.text
.globl main
main:
push {lr}
mov r0, #0
pop {lr}
mov pc, lr
.end
3.定义一个32位有符号数数组array
array: .word 0,1,2,3,4,5,6,7,8,9
4.计算数组的长度
C语言为:sizeof(array)/sizeof(array[0])
在32位系统中,一个word占4个字节,因此在计算好数组全部字节后,需要➗每个字节所占的大小
.equ length,( . - array)/4 //length=数组元素个数
5.定义一个用于输出的数据字段 关键字为 asciz、ascii、string
fmt1: .asciz "%8d"
6.主逻辑代码
6.1、初始化值
- 将r4赋值为0作为循环跳出条件的初始值
- 将数组的首地址存入r5寄存器
注意🎯寄存器r0,r1,r2,r3用于传递参数 建议大家非传参外从r4用起
我在之前用的r3去遍历数组的时候,一直报错,几个小时都找不到解决办法,后来看了顶文博主的文章后才明白!r0~r3最好别用!
mov r4,#0
ldr r5,=array
6.2、编写循环语句
思路分析: 1.设定循环条件,当设定的条件满足时,进入循环 1.1 将一个寄存器赋初值0 1.2 每打印一次,给寄存器加1,判断是否小于数组长度,小于则循环 2.打印第一个数 3.地址指针向下一个数组元素移动(+4位) 4.循环条件判断,进入循环打印下一个数或退出循环 |
-
设置循环标号,可以自定义哦
-
将寄存器中r5的地址对应的内容交给r1,然后r5+4将指针指向下一个地址(采用后变址寻址)
-
指定输出格式
-
调用C语言printf打印函数r1寄存器中的值
-
将r4增加1用于循环条件的判断
-
condition为自定义标号,下面会解释 不要着急哦 点我先看解释?
-
比较r4-length的差,但并不保存结果,可以根据flag标志寄存器来判断结果
-
如果r4小于length就继续循环 b为无条件跳转指令 lt意为小于(blt指小于的时候循环跳转!)
有小伙伴会问 🎯为什么不等于数组长度length呢?
是因为我们将r4赋初值为0,第一次比较后输出数组元素0…
当r4为9的时候输出数组元素9。下一次r4加1为10的时候,肯定就不能再循环啦,不然会溢出导致内存泄漏哦~
yh_loop:
ldr r1,[r5],#4
ldr r0,=fmt1
bl printf
add r4,#1
condition:
cmp r4,#length
blt yh_loop
7.完整代码
.data
fmt1: .string "%8d" //可以使用.asciz
fmt2: .string "\n" //增加一个打印完数组换行字段
array: .word 0,1,2,3,4,5,6,7,8,9
.equ length,( . - array)/4 //40÷4=10 →length=10
.text
.global main
main:
push {lr}
mov r4,#0
ldr r5,=array
b condition //首先需要判断一下条件是否满足 跳转到22行
yh_loop:
ldr r1,[r5],#4
ldr r0,=fmt1
bl printf
add r4,#1
condition:
cmp r4,#length
blt yh_loop //如果条件满足,则跳转到16行开始循环 每循环一次判断一次
ldr r0,=fmt2 //循环结束 将换行字段给r0
bl printf //负责将换行打印出来
mov r0,#0
pop {lr}
mov pc,lr
.end
8.运行结果
如何在Vs Code中使用Ubuntu(wsl)?
ps:
定义condition是因为我们需要提前判断一下我们的条件是否满足。如果不判断,则程序自上而下就会先进入循环打印一遍后才进行判断,如果我们提前进行判断,会免去不必要的发生。就好比C语言中while循环和do…while循环一样!
喜欢就点赞评论关注支持一下吧~😁😁😁
也欢迎大家一起讨论和指点错误哦~💌💌💌