• 嵌入式函数调用入栈与出栈


    简单的例程,几个函数调用,来查看寄存器状态,主要是学习一下cortem-M核中LR寄存器的理解:
    在这里插入图片描述
    例程源码:

    static uint32_t count_test = 0;
    
    static void fun3()
    {
    	count_test++;
    	
    }
    
    static void fun2()
    {
    	count_test++;
    	fun3();
        count_test++;
    }
    
    static void fun1()
    {
    	count_test++;
    	fun2();
    	count_test++;
    }
    
    int main(void)
    {
        fun1();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    通过单步调试来查看各个寄存器状态:

    step1

    进入调试界面
    在这里插入图片描述

    1. c源代码
    2. 对应的汇编代码
    3. 对应的当前寄存器
    step2

    记录当前进入main函数所要做的动作和记录的状态
    1、因main()函数中还有子函数,所以需将r4,lr寄存器压入栈中,对应的汇编:

    0x0800017A B510      PUSH     {r4,lr}
    
    • 1

    2、记住当前main函数中return 0处的代码地址:0x08000180
    在这里插入图片描述
    在进入fun1()函数后,会将返回地址的指针加1保存到LR寄存器中,即0x08000181,请记住这个值。

    step3

    进入fun1()
    在这里插入图片描述
    1、查看当前LR寄存器为0x08000181,与上述分析一致;
    2、进入当前fun1()函数中后,因为有子函数要执行,所以依然将r4,lr寄存器压入栈中
    3、记录代码中counnt_test++代码对应的地址:0x0800172,那么进入到fun2()函数之后的LR值应为:0x0800173
    在这里插入图片描述

    step4

    进入fun2()
    在这里插入图片描述
    分析同上,

    step5

    进入与退出fun3()
    在这里插入图片描述
    1、因fun3()函数中,没有子函数,r4,lr寄存器没有再进行入栈操作,执行结束之后直接返回,根据LR寄存器保存的返回地址:
    在这里插入图片描述

    step6

    退出到fun2()并准备进入fun3()
    在这里插入图片描述
    1、退出到fun2()时,因当前LR寄存器保存的还是进入fun3()时的值,现在要从退出到fun2()到退出到fun1(),那么对应的LR肯定就不对了,需进行出栈操作,如上图的汇编,将r4,pc出栈操作(pc就是lr,直接将lr的值赋给pc并执行),栈中存放的就是退出到fun1()地址处的值:

    0x08000162 BD10      POP      {r4,pc}
    
    • 1
    step7

    退出到fun1()并准备进入main()
    在这里插入图片描述
    道理同上。

    step8

    最终进入main()函数。
    在这里插入图片描述

    所以要记住的是:
    1、每次调用子函数,都会将返回的地址加1保存到LR寄存器中;
    2、如当前函数中还有子函数,则在进入子函数前需先压栈r4,lr,进行保护现场操作;
    3、而从函数中退出时,如果当前函数中有子函数,有过入栈操作,则在退出此函数时需进行出栈操作,根据出栈中保存的lr寄存器来返回需要退出的函数位置处。

      本文只是做了简单的记录,方便日后查看,后续再学习一下cortex-M核的几种工作模式及权限。

  • 相关阅读:
    【FPGA项目】图像采集及显示(3)总结
    「入门篇」初识JVM (下下) - GC
    国际短信平台哪家好?
    DOM——文件对象模型(元素位置、盒子模型)
    HTML期末作业 计算机毕业设计 html css javascript食品餐饮行业网站(10页)
    沃通签名验签服务器:保护关键业务信息真实可信
    Zookeeper 集群搭建
    java毕业设计基于精细化考核的离散数学课程教学目标达成系统Mybatis+系统+数据库+调试部署
    Qt给控件添加图片
    JVM内存设置与查看
  • 原文地址:https://blog.csdn.net/niu_88/article/details/127463274