函数调用过程的思考

为了深入理解函数的调用过程,我在STM32上使用JTAG来单步调试,观察通用寄存器和函数调用栈帧;
进入bsp_InitUart()之前,PC的值为0x08002B86,等于即将执行的指令地址(此时只是停在了断点处,还没有执行该指令)
在这里插入图片描述
进入bsp_InitUart()后,第一条指令:push {r4, lr}
意思是依次将lr, r4寄存器的内容压栈(按照约定,序号高的寄存器放在高地址),lr中保存的是函数bsp_InitUart()退出后的返回地址。
此时lr & pc寄存器的内容如图:
在这里插入图片描述
执行 push {r4, lr}指令后,sp -= 8(cortex栈是从高地址往低地址增长的),我们查看sp=0x20009770处的内容:
在这里插入图片描述
当bsp_InitUart()函数执行完后,最后一条指令是pop {r4, pc}:
(目的是从栈中读回,进入该函数时压栈保存的返回地址,让PC等于bsp_InitUart()函数的下一条指令,之后sp += 8)
在这里插入图片描述
执行完pop {r4, pc}指令后:
在这里插入图片描述
(1)sp的值 +=8 变为0x20009778,符合预期
(2)r4的值为0x08007174,符合预期
(3)而pc的值为何变为了0x08002B8A,而不是存在栈中的0x08002B8B???

查阅Cortex M3权威指南:
在这里插入图片描述
在这里插入图片描述
在第一张图里发生函数调用时,LR的值比预期+1 ,(下一条指令bsp_InitLed()地址为0x08002B8A,但是压入栈中的LR却是0x08002B8B)因为在分支时,无论是直接写 PC 的值还是使用分支指令,都必须保证加载到 PC 的数值是奇数(即 LSB=1),用以表明这是在 Thumb 状态下执行. 因为这个原因,所以在压栈LR时,LR等于下一条指令地址+1.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值