欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Cortex-M0 代码解析——01基本操作

程序员文章站 2022-06-07 08:48:43
...

1. 从复位到main初始化配置代码理解

看过Keil工程中的startup文件都知道,代码段起始是栈地址,随后是ResetHandle中断地址。
通过工具查看编译后的bin文件,获取ResetHandle地址,从而能够代码继续更进。比如:
(我代码起始地址配置了0x1000)
Cortex-M0 代码解析——01基本操作
在ResetHandle中,对于Cortex-M3比如stm32标准库而言,会提供时钟初始化等操作。Cortex-M0看各家芯片厂商如何配置的。随后都会调用如下代码进行跳转(其中__main中的代码,)
Cortex-M0 代码解析——01基本操作

1.1 __main中做了什么?

随后继续跟进,在__main中其实本质上是执行了如下几个操作:

  • 若有代码需要放于RAM中运行,则会进行代码重定向。(也即将相关的代码从code中搬移到ram区域)
  • 将data区数据,搬移到ram中,则该部分变量可读可写。
  • bss段清0。

汇编执行流程如下图所示:
Cortex-M0 代码解析——01基本操作
其中,一些简单的汇编理解,这里不再赘述。因为我觉得有耐心看我写的这篇文章的人,必定对汇编是有一定的了解的。其中特别关键的就是最下面那两个参数。(稍后有详细的计算说明)

我们查看keil编译后的map文件的时候,有两个重要的地址。见下:
(这个是我在另一个工程中摘出来的,地址和上述汇编不同,理解概念就好。不用纠结细节)

    Region$$Table$$Base                      0x000043ec   Number         0  anon$$obj.o(Region$$Table)
    Region$$Table$$Limit                     0x0000440c   Number         0  anon$$obj.o(Region$$Table)

汇编中的那两个参数便于此有关,从上面的汇编代码执行流程可以看出,
Region_Table_Base = 0x10B8 + 0x25D8 = 0x3690
Region_Table_Limit = 0x10B8 + 0x2608 = 0x36C0
共48字节。也即12个字。


其中,Region_Table_Base是一个基地址。从该地址处开始,以如下结构的方式进行顺序排列,到Region_Table_Limit为止。
Cortex-M0 代码解析——01基本操作

  • addr_src: 待搬移数据的源地址
  • addr_des: 待搬移数据的目的地址
  • len: 搬移的长度
  • copy_function: 数据搬移函数地址

从上面的数据中,可以看出相关的参数和对应的搬移函数的地址。也即调用了3个函数,进行了三种数据的搬移。


0x10C0——将放于ram中运行的代码段进行搬移,也即下图中的__scatterload_copy,第一次执行完毕,之后会返回的__scatterload_null标签的地址处继续执行。
Cortex-M0 代码解析——01基本操作
0x132E——是压缩数据的搬移,该部分通过压缩算法(应该是keil实现的吧?),将代码中data段被压缩的数据,解压缩后,搬移到相应的ram对应的空间中去。该部分的压缩和解压缩算法,下一个章节再详细描述(>@aaa@qq.com< 现在都晚上11点了,想睡觉了)

0x10DC——bss段清零函数
Cortex-M0 代码解析——01基本操作

1.2 执行完上述搬移之后,进入__rt_entry

Cortex-M0 代码解析——01基本操作
这部分代码中,主要执行配置栈和堆空间大小以及相关标准库的初始化等操作,这部分我没有太过于详细的理解。就不再说明了。最终进入main函数,开始执行开发者的代码。(简单介绍完毕 &_&)

2. 补充点题外话

    Total RO  Size (Code + RO Data)                 9228 (   9.01kB)
    Total RW  Size (RW Data + ZI Data)              5128 (   5.01kB)
    Total ROM Size (Code + RO Data + RW Data)       9344 (   9.13kB)

代码占用空间大小(常见都是下载到flash中的代码)就是ROM_Size
占用RAM空间大小为 RW_Size + Stack_Size + Heap_Size,其中堆和栈的大小都是在startup文件中配置的。
(当然了,还是那句话,这个是另一个工程中的map文件,大小的细节就不要在意啦。)

好的,简单介绍到这里,下一章节再做补充。

相关标签: 反汇编