【ARM汇编】如何对键入数据做判断?

举报
IM汤姆凯特 发表于 2022/04/21 23:58:33 2022/04/21
【摘要】 ARM汇编中如果键入多个数据,如何对键入的数据进行操作判断比较等操作处理?scanf键入应该放到哪里呢?

每日一句:
“我们人生的意义是什么?人生的目的在哪里?对于这个人生最基本的问题,我认为必须从正面回答。我的答案是:提升心性,磨练灵魂。”——稻盛和夫


【ARM汇编练习】如何对键入数据做判断?

写在前面:

当我们从键盘上输入一串数据,如何用ARM汇编语言对它进行判断是正数还是负数,并输出正数的个数和负数的个数。通过这次实操你可以了解对键入数据判断的两种方式,更熟悉在汇编中调用scanf使用方式,加深对判断指令使用方法的学习。那就一起来看一下今天的问题吧!

如何对键入数据的正负数做判断?

想要对键入数组做判断有两种方式:

1.把键入这个动作放到循环中,键入一次做一次判断
2.用循环把键入的数据全部放到数组中,然后再用循环对数组进行判断

今天带大家用第一种方式,把之前学过的scanf和判断语句结合起来练习一下

1先写出C语言的伪代码

在循环语句中加入键入,循环一次判断一次当前数是正数还是负数,然后计数处理。
#include<stdio.h>
int main()
{
	int z = 0,f=0, n = 0, i ;//z为正数,f为负数,n为要输入的数,i循环的次数 
	printf("输入数据:");
	for (i=0;i<5;i++)
	{
		scanf("%d", &n);
		if (n == 0) break;
		else if (n > 0) z++;
		else f++;
	}
	printf("正数有%d个,负数有%d个", z, f);
}

2.框架

上一篇我们实现了《对给定数组进行遍历,得出正负数的个数》

我们之前说过,学习新知识最快的办法是在已有的知识上迁移比对。因此《ARM嵌入式基础》这一专栏的内容是循序渐进的,每天学一点汇编加强对整体计算机结构的了解。

我们看一下,如果想要实现今天的功能,能用上一篇文章代码的哪一部分呢?

在这里插入图片描述

因为我们同《对给定数组进行遍历,得出正负数的个数》一样也是要进行判断、计数、输出,所以红框部分代码不需要变。

不同的是,我们这里没有数组,而是单独的一个数,需要做的就是把这个数放到循环中,并且给出支撑这个数的指令和支撑scanf的指令

理清了思路我们来看一下具体怎么实现

3.修改全局变量

1.把数组改为单独的一个数即可

2.声明scanf的格式串

.data
    fmt:.asciz "%d\n"
    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"
    a:.word 0

4.循环中调用scanf

调用scanf,必须给它获取到的值分配内存空间,在全局变量中已经声明a,这里我们需要把a的地址给r1,这样就可以将获取到的值传给a

        ldr r0,=fmt
        ldr r1,=a 
        bl scanf

5.对获取到的值进行判断

先将获取到的值存到了a中,想要对它进行判断,就要先获取到地址然后获取到内容。

由于调用过一次B,因此易失寄存器的值会改变,所以这里需要重新获取一次地址。

第一种方式:
    b testfor
loop: 
        ldr r0,=fmt
        ldr r1,=a 
        bl scanf

        ldr r1,=a 
        ldr r2,[r1]
        cmp r2,#0
        addgt r7,#1
        addgt r9,r2
        addlt r8,#1
        addlt r10,r2
第二种方式:

1.把分配内存的地址,先传给不易失寄存器。

2.scanf再用r1传到这个地址中。

3.所以就可以直接将不易失寄存器中的值取出来,用于判断。

    ldr r5, =a
    
    b testfor
loop: 
        ldr r0,=fmt
        ldr r1,=a 
        bl scanf

        ldr r2,[r5]
        cmp r2,#0
        addgt r7,#1
        addgt r9,r2
        addlt r8,#1
        addlt r10,r2

6.源代码

.data
    fmt:.asciz "%d\n"
    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"
    a:.word 0

.text
.globl main
 main:
    stmfd sp!,{lr}
    mov r4,#0
    mov r7,#0
    mov r8,#0
    mov r9,#0
    mov r10,#0
    ldr r5, =a
    
    b testfor
loop: 
        ldr r0,=fmt
        ldr r1,=a 
        bl scanf

        ldr r2,[r5]
        cmp r2,#0
        addgt r7,#1
        addgt r9,r2
        addlt r8,#1
        addlt r10,r2
        
        add r4,#1
testfor:cmp r4,#5
        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, #0
    ldmfd sp!,{lr}
    mov pc, lr
.end

7.运行验证


这里需要注意的是,当循环五次后,还得键入一个任意字符用于结束循环。我们后面讲到先将键入数据存到数组中就会避免这种事情发生。

在这里插入图片描述

总结

  • 对键入数据进行判断有两种方式,这里用到的是实时判断然后累计

  • 练习了对C语言函数的调用和判断后缀使用

  • 使我们产生一个疑问:输入结束需要键入一个随机字符才能结束循环,怎么产生的?怎么才能避免?


本期就结束了,如果对你有帮助,点赞+收藏支持一下博主再走吧
还没有关注汤姆的朋友,点个关注每天学一点汇编
下期预告:【ARM汇编】如何将键入的数据存到数组中?

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。