本文的资料下载
https://download.youkuaiyun.com/download/qq_25140013/11987455
分析程序下载的内容和位置
程序下载的内容为 arm.bin的二进制内容
仿真内的flash数据
1、启动文件的分析
这里程序的开始从复位开始分析,
PC指向08000845,指向20010000
1、Reset_Handler跳转到LoopCopyDataInit,顾名思义,循环复制数据初始化段,
2、首先我们分析LoopCopyDataInit执行到CopyDataInit段的汇编,
(这里面为了分析简单均省去0x)
r0=20000000,r3=20000430,r2=r0+r1=20000000,比较r2和r3是否相等,如果不等,跳到CopyDataInit去执行,CopyDataInit的汇编功能,r3=08000a90,r3=[08000a90]=0000001e(改为)=0x44aa200
由于bin文件数值是0x44aa200,和编译器仿真的是一样的,我们不仅的猜测反汇编是不是有问题,
是不是由于工具的反汇编问题,这里就不讨论了,
接着分析吧,
将r3=0x44aa200,存储到r0+r1=0x20000000处,也就是ram的首地址处,然后r1=0x04,然后又进入了LoopCopyDataInit中,r0=0x20000000,r3=0x20000430,r2=r1+0x04=0x20000004,然后比较r2是否和r3相等,然后跳到CopyDataInit中,r3=0x8000a90,r3=[0x8000a90+0x04]=0x00000000,然后将r3的值存储在r0+r1=0x20000000+0x04=0x20000004中,一次类推,可以知道,这段汇编的作用是,将0x8000a90到0x8000a90+(0x200004300-0x20000000)处的内容赋值到0x2000000到0x20000430中,然后我们就可以分析,0x8000a90到0x8000EC0这段内容到底是什么含义呢,
0x8000a90到0x8000EC0刚刚好是Flash的最后一段地址,
通过stm32_flash.ld文件可以看,是。fini_array段
map文件可以看到,
总结一下,将 fini_array内容赋值到.data中
3、LoopCopyDataInit调LoopFillZerobss,而LoopFillZerobss调用FillZerobss
分析汇编r2=0x20000430 然后调用LoopFillZerobss函数,r3=0x20000584,比较r3和r2是否相同,然后跳转FillZerobss,r3=0,将r3写到r2=0x20000430地址中并且r2=0x20000434,然后r3= 0x20000584,依次类推可以知道,该段汇编的作用是,将RAM地址0x20000430 ~0x20000584清空为0
0x20000430 ~0x20000584是内存的什么段呢,.bss段了
4 LoopFillZerobss跳转到SystemInit段中
由于SystemInit代码过于庞大,就没必要分析了,反正sp已经指向0x20010000处可以用c代码进行分析了,
这里就介绍c代码怎么分析了,c语言还是挺简单的,配置配置时钟,向量表,回到C的世界就不多啰嗦了,
执行完SystemInit之后,现象
5、LoopFillZerobss调用__libc_init_array
由于不能做到__libc_init_array的C代码,分析汇编可读性太差,这里就不分析了
执行完__libc_init_array 之后,msp和psp都没变化,内存也没变化,
6、LoopFillZerobss跳到main函数中
经过以上的 分析进入我们熟悉的main函数中,
这里灯就已经点亮了,到此本文结束了,
本文的案例工程下载见
https://download.youkuaiyun.com/download/qq_25140013/11987455