MDK __main()代码执行分析
来源:互联网 发布:成都九龙医院网络预约 编辑:程序博客网 时间:2024/06/06 03:46
__main()代码执行分析
STM32启动代码主要是分配堆栈及设置向量表,然后跳转到__main函数。
跳转具体到代码段部分如下:
Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main LDR R0, = __main BX R0 ENDP
当您看到__main函数时,估计应该有不少人认为这个是main函数的别名或是编译之后的名字,否则在启动代码中再也无法找到和main相关的字眼了。可事实是,__main和main是完全两个不同的函数,并且你无法找到__main代码,因为这个是编译器自动创建的。
查看MDK的文档,会发现有这么一句说明:It is automatically created by the linker when it sees a definition of main()。简单点来说,当编译器发现定义了main函数,那么就会自动创建__main。
程序经过汇编启动代码,执行到__main()后,可以看出有两个大的函数:
__scatterload():负责把RW/RO输出段从装载域地址复制到运行域地址,并完成了ZI运行域的初始化工作。
__rt_entry():负责初始化堆栈,完成库函数的初始化,最后自动跳转向main()函数。
分析__scatterload()函数
执行到__main(),先跳转到_scatterload下图红框框中代码所示,执行完后,R10和R11就被赋给成了下面两个值。
Map文件中的symbol
然后执行_scatterload_null代码,将R10对应地址存放的的4个字copy到R0~R3中,可以看出
R0:0x1000表示的是keyled.o加载域起始地址
R1:0x30000100为keyled.o运行域地址
R2:0X160为copy的大小,keyled.o的大小从map文件中得知就是0x160 Byte
R3:0X1E4 是_scatterload_copy 代码的起始地址,实用BXR3 就能跳转到_scatterload_copy来复制代码。
跳到_scatterload_copy,开始copy,循环0x16次,每次搬移4个字(16Byte),共搬移0x16*0x10=0x160
复制完keyled.o代码后,进一步循环到_scatterload_null准备好,ZI段需要清零的地址和范围
执行完这个循环后
R1:0x30050000 为ZI段的起始地址
R2:0x618为ZI段大小,换成十进制是1560.从map文件得知ZI大小就是1560Byte
R3:0x20c 为_scatterload_zeroinit 的地址
执行下面红框框中循环体,共清零0x610Byte范围,然后再执行蓝框框中代码,清零8Byte,总共0x618
ZI段清零(0x30050000~0x30050618)
然后使用BX R14跳转到0x000001BC处,顺序执行到BL __rt_enty 指令
成功跳转到__rt_enty函数
分析__rt_entry()函数
先调用__user_setup_stackheap()函数来建立堆栈
可以看出在这个函数中,会执行到BL__user_initial_stackheap()函数,这样也就明白了,为什么使用分散加载文件,需要设置__user_initial_stackheap这个函数来设置堆栈空间。
- MDK __main()代码执行分析
- MDK __main()代码执行过程分析
- 分析MDK启动代码__main
- MDK启动代码__main(),__rt_entry()分析
- MDK __main过程分析
- __main代码分析
- MDK main()函数执行前汇编代码分析
- STM32 keil mdk启动代码发分析
- STM32 keil mdk启动代码发分析
- STM32 keil mdk启动代码发分析
- STM32 keil mdk启动代码发分析
- STM32 keil mdk启动代码发分析
- STM32 keil mdk启动代码发分析 .
- MDK S3C2440启动代码简单分析
- STM32 keil mdk启动代码发分析 .
- STM32 keil mdk启动代码发分析
- STM32 keil mdk启动代码发分析
- STM32 keil mdk启动代码发分析
- 使用微软的 ilasm 和 ildasm 对. net程序进行编译和反编译
- Embedding LuaJIT in 30 minutes (or so)
- Android Studio如何自动 import
- api加密
- pwnable之blackjack
- MDK __main()代码执行分析
- 【Git配置技巧】01. 配置文件git config介绍 --[码农老毕的学习笔记]
- 关于前端页面需要用到特殊的字体,如果UI给的字体语言内码为中文(gb2312),如何解决?
- Objective-c 内存管理-内存泄漏
- linux的crontab等命令
- Tricks(二十五)—— decorator(在函数调用前后打印日志)
- qt 信号槽默认参数 toggled 和 trigger的区别
- SVN Unable to connect to a repository at URL
- c++第三次实验——个人所得税计算器