先用C语言来实现这个功能,便于明确要实现功能的思路 C语言代码: #include<stdio.h>
int main(){
int ary[10] = {0,-1,2,3,4,5,-6,7,8,9};
int sum1=0,sum2=0, i;
int z=0,f=0;
for ( i = 0; i < 10; i++)
{
if(ary[i]>0){
z=z+1;
sum1 =sum1 +ary[i];
}
else if(ary[i]<0){
f=f+1;
sum2 =sum2 +ary[i];
}
}
printf("正数的个数为:%d\n负数的个数为:%d\n",z,f);
printf("正数的和为:%d\n负数的和为:%d\n",sum1,sum2);
return 0;
}
运行结果: ![在这里插入图片描述](https://res.hc-cdn.com/ecology/9.3.130/v2_resources/ydcomm/libs/images/loading.gif) 1.2参照正向遍历的框架
学习任何东西最快速的办法是,调取大脑中已有的知识,让新知识跟旧知识进行对比和延伸思考。
把正向遍历的程序贴过来,发现实现整体功能的框架基本不变,只需要把循环中的这一部分操作改一下即可。把步骤拆开,详细细分为下面几步,我们一起来看一下。
![在这里插入图片描述](https://res.hc-cdn.com/ecology/9.3.130/v2_resources/ydcomm/libs/images/loading.gif) 2.编写ARM汇编 2.1先给定一串数组、输出格式
这里要尝试输出正数的个数、负数的个数以及正数之和、负数之和;数组用ary自定义;通过地址长度计算出要循环的次数 .data
fmt1:.asciz " The number of positive:%d\n The number of negative:%d\n"
fmt2:.asciz " The positive and:%d\n The negative and:%d\n"
ary:.word 0,-1,2,3,4,-5,6,7,8,-9
.equ counter,( . - ary)/4
2.2在循环中加入判断、计数
这一步就是核心步骤,用汇编写if判断语句。之前给出过所有的指令,其中CMP用来判断。与CMP紧密联系在一块的就是加判断后缀的指令,这个指令可以是跳转(B)可以是(ADD)也可以是(MOV)。
要实现的功能:把数组中的第一个值取出来,然后与零进行判断,当大于零时,给正数的计数器加一,并且给正数的累加和加上当前数值。判断为负数时则相反。 ARM汇编实现方法: ldr r2,[r5],
cmp r2,
addgt r7,
addgt r9,r2
addlt r8,
addlt r10,r2
如果在x86中只能是CMP比较完用BLT跳转到子程序,执行完再跳转回来,ARM对于判断就方便很多,可以直接加在想要比较后想要执行的语句上。并且只需要一次比较。后面可以跟很多个,比较后想要执行的代码。
2.3在主函数中初始化使用的寄存器 一般定义寄存器都是在完成核心代码之后,查看核心代码中用到了哪些寄存器,然后给对应的寄存器赋初始值 这里的寄存器分别表示:
r7用来存放正数的个数
r8用来存放负数的个数
r9用来存放正数之和
r10用来存放负数之和
这里用到的R4和R5和之前一样没有变化依旧是:循环变量和数组首地址
mov r4,
mov r7,
mov r8,
mov r9,
mov r10,
ldr r5, =ary
2.4输出累计之和
-
想要打印输出肯定是用到printf,那就得先调用输出的格式串,格式串在最开始就已经定义好。 -
printf是从R1开始输出的所以要把我们需要的值正负数个数、正负数和,传递给R1、R2。 -
下面部分由于已经打印出来,所以就可以把R1、R2覆盖,并且当用B跳转一次,R0~R3的值都会变化,最好都要重写。
ldr r0,=fmt1
mov r1,r7
mov r2,r8
bl printf
ldr r0,=fmt2
mov r1,r9
mov r2,r10
bl printf
2.5源代码 .data
fmt1:.asciz " The number of positive:%d\n The number of negative:%d\n"
fmt2:.asciz " The positive and:%d\n The negative and:%d\n"
ary:.word 0,-1,2,3,4,-5,6,7,8,-9
.equ counter,( . - ary)/4
.text
.globl main
main:
stmfd sp!,{lr}
mov r4,
mov r7,
mov r8,
mov r9,
mov r10,
ldr r5, =ary
b testfor
loop:
ldr r2,[r5],
cmp r2,
addgt r7,
addgt r9,r2
addlt r8,
addlt r10,r2
add r4,
testfor:cmp r4,
blt loop
ldr r0,=fmt1
mov r1,r7
mov r2,r8
bl printf
ldr r0,=fmt2
mov r1,r9
mov r2,r10
bl printf
mov r0,
ldmfd sp!,{lr}
mov pc, lr
.end
这里我们值需要判断正负计数即可,因为零既不属于正数也不属于负数
2.6运行结果 可以看到结果是正确的! ![在这里插入图片描述](https://res.hc-cdn.com/ecology/9.3.130/v2_resources/ydcomm/libs/images/loading.gif) 3.总结
- 对给定数组进行操作时,要把操作放入循环中,并且通过寄存器向后寻址的方式循环。
- 给出了所有的判断后缀,在ARM中可以把判断后缀放到任意的指令后,用于判断后的执行操作;一条CMP指令可以跟很多条判断执行操作。
- 编写汇编时,先写出核心代码部分,再给主函数、全局变量、输出语句中添加支撑条件。
本期就结束了,如果对您有帮助,点赞+评论支持一下博主再走吧
还没有关注汤姆的朋友,点个关注每天学一点汇编
下期预告:【ARM汇编】用汇编向数组添加元素
![在这里插入图片描述](https://res.hc-cdn.com/ecology/9.3.130/v2_resources/ydcomm/libs/images/loading.gif)
|
|
|
|
评论(0)