Cortex-M3/M4内核STM32的LR寄存器和PC寄存器

怎么控制STM32跳转到指定程序:

  • 首先,使用标号加goto语句可以使程序强制跳转,而goto的原理实际上是汇编语言里面的强制跳转。
  • 我们看STM32的启动文件,发现里面有这两句程序:
    在这里插入图片描述
  • 其中:
    LDR R0 ,=一个函数名:意思是把这个函数的地址放到寄存器R0里面。
    BLX R0BX R0:意思都是跳转到以R0寄存器所存的地址。

STM32的LR寄存器和PC寄存器:

  • Cortex-M3架构共有R0-R15共16个寄存器,每个寄存器都是32位的。
    R15叫做PC寄存器,意思为程序计数器,内部存的是程序当前执行到了哪个地址。
    R14叫做LR寄存器,意思为连接寄存器,在执行子函数前,LR会保存执行完子函数后,应该回到哪个地方。
    验证如下:
  • 我们在主函数执行里面打一个断点,当程序执行到断点处时,我们发现断点处的PC指针是0X080002A2。如下:
    在这里插入图片描述
  • 由于历史原因,最初的16位单片机用的指令是Thumb指令,为16位指令。后来,ARM推出了32位的ARM指令。16位的指令更适合空间有限的嵌入式处理器,而32位的指令则更加灵活、功能丰富。因此,有些单片机在运行时可以根据需求切换指令状态。如下图:
    在这里插入图片描述
  • 后来诞生了Thumb-2指令集,它实现了16位指令和32位指令的共存。而Cortex-M3架构则就是采用Thumb-2指令集。由于16位指令长度是2字节,32位指令长度是4字节,因此其PC指针地址是按照2字节(16位)对齐的。换言之其最低位一定是0。
  • 我们发现第一个断点处PC指针:0X080002A2符合这个特点。
    在这里插入图片描述
    在这里插入图片描述
  • 下面是PC寄存器对齐说明。
    在这里插入图片描述
  • 接着回到我们打的断点处。
    在这里插入图片描述
  • 断点处的上一句执行的是函数raw_os_init()
  • 按照我们的推论,在跳转到函数**raw_os_init()前,LR寄存器会记住执行完raw_os_init()函数后,PC指针应该回到哪个地址。
    因此我们在
    raw_os_init()函数里面打断点,看执行子函数raw_os_init()**时LR是不是存的是执行完子函数后应该返回的地址。如下图:
    在这里插入图片描述
  • 在执行子函数raw_os_init()时,我们发现LR里面存的是0X080002A3,而执行完改函数后应当回到的地址是0X080002A2,我们发现比我们在temppp += 1;断点处看到的PC指针大了1。这是为什么呢?
  • 首先我们观察LR寄存器内存放的值:0X080002A3,其最低位为1,显然不可能是直接存放的程序地址,因为程序地址需要2字节对齐,最低位为0。
  • 我们继续看资料发现,原来LR寄存器的最低位是标识指令长度状态的。
    在这里插入图片描述
  • 在以LR存放的地址进行跳转时,会将最低位与0。而与00X080002A3就变为了0X080002A2,即要回到的地址。

对指令感兴趣的可以继续往下看:

在《权威指南》一书中,有以下说明:

  • 首先是Cortex-M3架构的创新性指令集:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

Cortex-M3架构的优点之一就是采用了Thumb-2指令集,其同时支持16位指令和32位指令共存,而不会混淆。
而只所以不会混淆,并不可能是存在什么魔法能够让CPU自动分辨指令长度,必定存在一个标志位,来标识每一条指令的类别是16位还是32位。

  • 我们对比LR和PC特点,发现PC最低位一定是0,那么LR存放的数据中,最低位就相当于多余的,因此我们可以拿LR最低位来做标志位,来标识一些信息。恰好,我们上边16位指令还是32位指令缺少个标志位,因此,LR寄存器的最低位是Thumb状态标志位,如下:
    在这里插入图片描述

2023年3月31日删除下面错误:
这是因为我们在temppp += 1;打断点时,是还没执行temppp += 1;语句的PC指针地址,则执行temppp += 1;时PC指针值应该是0X080002A2 + 1=0X080002A3,刚好和LR寄存器中存的值一样。

2024年1月12日更正下面错误:
换言之其最低2位一定全是0,我们发现0X080002A2符合这个特点

结语:

LR寄存器存的是:执行子函数后,PC指针应该跳转回去的地方。

  • 12
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
Cortex-M3和Cortex-M4ARM架构的微控制器。它们广泛应用于嵌入式系统和物联网设备中,具有高性能、低功耗和强大的性能优化能力。 Cortex-M3和Cortex-M4使用的指令集是ARMv7-M架构,其中包含了大量的指令,用于实现各种功能和操作。下面是这两种微控制器常用的指令集: 1. 数据处理指令:这些指令用于对数据进行处理和操作,比如加法、减法、移位等。Cortex-M3和Cortex-M4支持32位整数和浮点数的处理指令,可以高效地执行各种数学运算。 2. 控制指令:这些指令用于控制程序的流程,比如条件判断、跳转和函数调用等。Cortex-M3和Cortex-M4支持分支指令、循环指令和中断指令,可以实现灵活的控制流程和异常处理能力。 3. 存储器访问指令:这些指令用于对存储器进行读写操作,包括读取数据、存储数据和移动数据等。Cortex-M3和Cortex-M4支持多种不同的存储器访问指令,包括字节访问、半字访问和字访问等,可以高效地操作各种类型的存储器。 4. 特殊功能寄存器指令:这些指令用于对特殊功能寄存器进行读写操作,包括配置系统控制寄存器、中断寄存器和电源管理寄存器等。Cortex-M3和Cortex-M4提供了一套完整的特殊功能寄存器指令集,方便对系统进行配置和管理。 总结来说,Cortex-M3和Cortex-M4常用的指令集主要包括数据处理指令、控制指令、存储器访问指令和特殊功能寄存器指令。这些指令可以满足微控制器在嵌入式系统和物联网设备中的各种需求,实现高效、低功耗的数据处理和控制功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天城寺电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值