MDK_main()代码执行过程分析

1.1     __main()代码执行分析

以keyled程序为例说明,keyled代码请参考我的博客网址:http://my.csdn.net/wfq0624/code/detail/7645

 

程序经过汇编启动代码,执行到__main()后,可以看出有两个大的函数:

__scatterload():负责RW/RO输出段从装载域地址复制到运行域地址,并完成了ZI运行域的初始化工作。

__rt_entry():负责初始化堆栈,完成库函数的初始化,最后自动跳转向main()函数。

 

分析__scatterload()函数

执行到__main(),先跳转到_scatterload下图红框框中代码所示,执行完后,R10和R11就被赋给成了下面两个值。

Map文件中的symbol

Region

TableTable
Base               0x00000394   Number         0 anon
obj.o(Regionobj.o(Region
Table)

Region

TableTable
Limit               0x000003b4   Number         0 anon
obj.o(Regionobj.o(Region
Table)


然后执行_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这个函数来设置堆栈空间。

原文出处:点击打开链接https://blog.csdn.net/wangfoquan/article/details/7650988


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
查看文章 STM32 keil mdk启动代码分析_转2010年01月29日 星期五 13:50 ;// Stack Configuration ;// Stack Size (in Bytes) ;// Stack_Size EQU 0x00000200 ;//定义堆栈大小 AREA STACK, NOINIT, READWRITE, ALIGN=3 ;//定义一个数据段 按8字节对齐 ;AREA 伪指令用于定义一个代码段或数据段 NOINIT:指定此数据段仅仅保留了内存单元,而没有将各初始值写入内存单元,或者将各个内存单元值初始化为0 Stack_Mem SPACE Stack_Size ;//保留Stack_Size大小的堆栈空间 分 配连续 Stack_Size 字节的存储单元并初始化为 0 __initial_sp ;//标号,代表堆栈顶部地址,后面有用 ;// Heap Configuration ;// Heap Size (in Bytes) ;// Heap_Size EQU 0x00000020 ;//定义堆空间大小 AREA HEAP, NOINIT, READWRITE, ALIGN=3 ;//定义一个数据段,8字节对齐 __heap_base Heap_Mem SPACE Heap_Size ;//保留Heap_Size的堆空间 __heap_limit ;//标号,代表堆末尾地址,后面有用 PRESERVE8 ;//指示编译器8字节对齐 THUMB ;//指示编译器为THUMB指令 ; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY ;//定义只读数据段,其实放在CODE区,位于0地址 EXTERN NMIException EXTERN HardFaultException EXTERN MemManageException EXTERN BusFaultException EXTERN UsageFaultException EXTERN SVCHandler EXTERN DebugMonitor EXTERN PendSVC EXTERN SysTickHandler ;//声明这些符号在外部定义,同C ;//在××it.c中实现这些函数 ,中断就能自动调用了 EXPORT __Vectors EXPORT __initial_sp ;EXPORT:在程序中声明一个全局的标号__Vectors,该标号可在其他的文件中引用;I
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值