【ARM汇编应用】调用C语言中的scanf函数

举报
IM汤姆凯特 发表于 2022/04/19 17:19:28 2022/04/19
【摘要】 ARM汇编实现输入两个数求和在输出 | ARM汇编调用C语言中的scanf函数 | ARM汇编调用printf函数 | ARM汇编新模板

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

凡有的,还要加倍给他,叫他多余;没有的,连他所有的也要夺过来——《新约·马太福音》

 写在前面

大家都知道,C语言的直接底层属于汇编,汇编不仅仅是C语言的基础,也是计算机运行的基石。

既然C和汇编这么近,那我们必然要学会汇编调用C语言的函数,来方便我们实现更多功能。

今天给大家介绍怎么用ARM汇编语言调用scanf函数。

我们仍然用《从键盘上输入两个数,求和然后输出》这个例子来学习

        这里就用到了scanf函数,scanf的定义是:按用户指定的格式从键盘上把数据输入到指定的变量之中。

ARM中scanf的用法

1.在ARM汇编中用scanf输入的数据存储到内存中,如果在内存中有定义变量,就会存到变量中,如果没有定义随机存储到一个地址,所以要先在内存中定义存到哪

2.跟printf一样可以直接使用 BL scanf 调用,但是每当用BL跳转一次都要重新定义一次R0~R3,传递参数只能用R1~R3

知道了关于scanf在ARM中的用法,下面就带着大家来写一写ARM汇编的《从键盘上输入两个数,求和然后输出》

第一步,把框架给搞出来

  • 前面给大家介绍了,汇编的基本框架,【ARM汇编基本框架与两数求和
  • 这里给大家一个新的ARM汇编的编程框架,跟之前的道理是一样的,把压栈和弹出用push和pop简洁替代了
.data
    ………………
.text
.globl main
 main: 
   push {lr}                
     ………………  
   mov r0, #0             
   pop  {lr}           
   mov pc, lr   
.end

第二步,声明全局变量和符号常量

  • 1.先把printf和scanf的输入输出格式声明好
  • 2.由于想要调用scanf输入两个数,所以必须先在内存中定义两个变量
.data
    fmt:.asciz "\n  sum=%d\n"
    fmt1:.asciz "%d %d"
    a:.word 0
    b:.word 0

第三步,输入两个数存到内存中

  • 在传递参数时只能用R0~R3,在调用scanf时必须要将内存中要存放输入数据的变量地址先取到寄存器中。
        ldr r0, =fmt1
        ldr r1,=a 
        ldr r2,=b 
        bl scanf

第四步,从内存中读取数据

  • 上一篇说到过,从内存中取数据需要两步,先通过LDR伪指令取地址,然后通过间接寻址的方式把值传给寄存器进行运算。
    ldr r1,=a 
    ldr r1,[r1]
    ldr r2,=b 
    ldr r2,[r2]

第五步,运算然后输出

    add r2,r1
        ldr r0,=fmt
        mov r1,r2
        bl printf

R0~R15本质上就是地址的别名。这里要注意,每次调用B指令时,R0~R3中的值都会变化,所以一定要重新进行赋值

运行的结果就不给大家看了,大家可以试着敲一下,如果哪里有问题可以通过评论区告诉我。


最后,用实现《输入三个数然后求和输入》来验证我们是否学会呀!


源代码:

.data
    fmt:.asciz "\n  sum=%d\n"
    fmt1:.asciz "%d %d %d"
    a:.word 0
    b:.word 0
    c:.word 0
.text
.globl main
main:
    stmfd sp!,{lr}
        ldr r0, =fmt1
        ldr r1,=a 
        ldr r2,=b 
        ldr r3,=c
        bl scanf
    ldr r1,=a 
    ldr r1,[r1]
    ldr r2,=b 
    ldr r2,[r2]
    ldr r3,=c
    ldr r3,[r3]
    add r2,r1
    add r3,r2
        ldr r0,=fmt
        mov r1,r3
        bl printf
    mov r0,#0
    ldmfd sp!,{lr}
    mov pc,lr
.end

结果:


本期就结束了,如果对您有帮助,点赞+评论支持一下博主再走吧

还没有关注汤姆的朋友,点个关注每天学一点汇编

下期预告:【ARM汇编的循环运用】正向遍历|逆向遍历



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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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