• 从最简单的实例学习ARM 指令集(三)


          上一篇讲到赋值运算,这篇讲讲子函数调用。先看最简单范例:test4.c

    #include <stdio.h>
    void f1()
    {
    }
    void main()
    {
      int d = 4;
      f1();
    }

          然后编译:arm-linux-gnueabihf-gcc test.c -o test4

          然后看看汇编代码:

    0000835c <f1>:
    1    835c:       b480            push    {r7}
    2    835e:       af00            add     r7, sp, #0
    3    8360:       46bd            mov     sp, r7
    4    8362:       bc80            pop     {r7}

    直接跳到main函数里调用此函数时保存的LR值:
    5    8364:       4770            bx      lr
    6    8366:       bf00            nop

    00008368 <main>:

    程序用到了r7寄存器,所以须要保护以免破坏之前的数据,同一时候由于本函数调用子函数f1。须要用到lr寄存器保存返回值。故须要保存LR到栈里:


    7    8368:       b580            push    {r7, lr}
    8    836a:       b082            sub     sp, #8
    9    836c:       af00            add     r7, sp, #0
    10    836e:       f04f 0304       mov.w   r3, #4
    11    8372:       607b            str     r3, [r7, #4]

    跳转到函数f1的地址,同一时候把返回地址保存到LR寄存器:
    12    8374:       f7ff fff2       bl      835c <f1>
    13    8378:       f107 0708       add.w   r7, r7, #8
    14    837c:       46bd            mov     sp, r7

    注意:此时不再使用bx lr返回了!

    而是直接把第7行保存的LR值弹到PC寄存器上,下一条取地址指令就是取main函数的下一个地址。

    事实上。採用原来的方式:pop {r7, lr} 以及 bx lr 返回也是能够的。仅仅只是会多使用一条指令:
     15   837e:       bd80            pop     {r7, pc}

            细心的人会发现。汇编代码8-11行与《从最简单的实例学习ARM 指令集(一)》中的范例test1.c一模一样。f1函数的机器指令十分简单,就是r7寄存器的压栈与出栈,相信大家都能看懂。

    不知道大家有没有注意到,从main函数跳转到f1用的是bl指令,而从f1返回调用的是bx指令?

            事实上这是由于涉及到arm处理器的两种工作状态:arm和thumb。子函数返回须要推断lr寄存器的[0]位来决定arm工作在那种状态,对子函数来说。偷懒的做法就是:无论主函数是什么。返回是虽然使用bx。让arm自己推断。而对main函数这样调用者来说。是知道当前处理器工作在thumb还是arm状态的,所以仅仅须要使用bl就能够了。

           总结一下子函数的调用规则就是:bl用在函数内。bx用在返回。

           下一篇讲讲函数调用过程中。參数是怎样传递的。



  • 相关阅读:
    批处理详细教程1
    “无后端”的web应用开发模式
    给Notepad++换主题
    Github for Windows使用图文教程
    MongoDB操作数据库的几个命令(自己用)
    P2P实现的原理
    ios中摄像头/相册获取图片压缩图片上传服务器方法总结
    ffmpeg编译
    UIScrollView的contentSize、contentOffset和contentInset属性
    sqllite相关总结
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6752413.html
Copyright © 2020-2023  润新知