原创 keil MDK运行时库分析02

2009-10-9 20:07 5387 6 6 分类: MCU/ 嵌入式

二、步骤续
11、在__rt_stackheap_init中
                 __rt_stackheap_init:
0x0800179A 4674      MOV      r4,lr;将返回地址保存在R4中;
0x0800179C F000F82E  BL.W     __user_setup_stackheap (0x080017FC)
0x080017A0 46A6      MOV      lr,r4
0x080017A2 B50D      PUSH     {r0,r2-r3,lr};第一次用到了堆栈,保存了程序返回值。
0x080017A4 F000F850  BL.W     __rt_stackheap_storage (0x08001848)
0x080017A8 0004      MOVS     r4,r0;子程序的返回值。
0x080017AA E8BD400D  POP      {r0,r2-r3,lr}
0x080017AE 0011      MOVS     r1,r2
0x080017B0 4770      BX       lr
12、在__user_setup_stackheap中,
0x080017FC 4675      MOV      r5,lr;将返回地址保存在R5中;
0x080017FE F000F8A5  BL.W     0x0800194C;
13、0x0800194C的功能分析;该段程序在_sys_exit中。
0x0800194C 4800      LDR      r0,[pc,#0]  ; @0x08001950
0x0800194E 4770      BX       lr;将0x2000 0040保存在r0中,返回。


14、 __user_setup_stackheap:继续
                 __user_setup_stackheap:
0x080017FC 4675      MOV      r5,lr
0x080017FE F000F8A5  BL.W     0x0800194C
0x08001802 46AE      MOV      lr,r5;从上面返回后,恢复lr
0x08001804 0005      MOVS     r5,r0
0x08001806 4669      MOV      r1,sp
0x08001808 4653      MOV      r3,r10
0x0800180A F0200007  BIC      r0,r0,#0x07
0x0800180E 4685      MOV      sp,r0
0x08001810 B018      ADD      sp,sp,#0x60;堆栈的起始点0x2000 00a0.
0x08001812 B520      PUSH     {r5,lr}
0x08001814 F7FEFCB2  BL.W     __user_initial_stackheap (0x0800017C)
15、 __user_initial_stackheap ;
    跳到用户定义的函数,因为堆栈和用户堆得大小都是在程序中
自己定义的。
    在用户程序中定义的BX LR就是返回到该函数中。
0x08001818 E8BD4020  POP      {r5,lr}
0x0800181C F04F0600  MOV      r6,#0x00
0x08001820 F04F0700  MOV      r7,#0x00
0x08001824 F04F0800  MOV      r8,#0x00
0x08001828 F04F0B00  MOV      r11,#0x00
0x0800182C F0210107  BIC      r1,r1,#0x07
0x08001830 46AC      MOV      r12,r5
0x08001832 E8AC09C0  STM      r12!,{r6-r8,r11}
0x08001836 E8AC09C0  STM      r12!,{r6-r8,r11}
0x0800183A E8AC09C0  STM      r12!,{r6-r8,r11}
0x0800183E E8AC09C0  STM      r12!,{r6-r8,r11}
0x08001842 468D      MOV      sp,r1;将sp设置为0x0800 04a0;
0x08001844 4770      BX       lr;返回到前一级程序__user_setup_stackheap。
16、在__user_setup_stackheap继续执行
0x080017A0 46A6      MOV      lr,r4;将保存在R4中的子程序返回值送回LR。
0x080017A2 B50D      PUSH     {r0,r2-r3,lr};利用堆栈保存参数。
0x080017A4 F000F850  BL.W     __rt_stackheap_storage (0x08001848)
在该程序中,主要是在r0中保存了一个值0x2000 0050。
0x080017A8 0004      MOVS     r4,r0;返回值保存到r4中。
0x080017AA E8BD400D  POP      {r0,r2-r3,lr}
0x080017AE 0011      MOVS     r1,r2
0x080017B0 4770      BX       lr;回到__rt_entry中执行。
17、又回到__rt_entry了,其实走了一圈,具体也没做什么事。
0x080017C6 B403      PUSH     {r0-r1}
0x080017C8 F000F93C  BL.W     _platform_post_stackheap_init (0x08001A44);具体平台的堆栈相关初始化:本程序中没做什么事,估计是可以人工定义改变的。
0x080017CC BC03      POP      {r0-r1}
0x080017CE F000F8D9  BL.W     __rt_lib_init (0x08001984)


18、进入__rt_lib_init
0x08001984 E92D43FE  PUSH     {r1-r9,lr}
0x08001988 4604      MOV      r4,r0
0x0800198A 460D      MOV      r5,r1
0x0800198C F000F872  BL.W     _fp_init (0x08001A74);进入浮点初始化
19、进入 _fp_init
0x08001A74 B510      PUSH     {r4,lr}
0x08001A76 F7FFFFF7  BL.W     __rt_fp_status_addr (0x08001A68);马上又进入到__rt_fp_status_addr。
0x0800198C F000F872  BL.W     _fp_init (0x08001A74);回来了,其实也没做什么事,就在0x2000 0044处存了一个数据,什么用途暂时不知。
0x08001990 2000      MOVS     r0,#0x00
0x08001992 E9CD4500  STRD     r4,r5,[sp,#0]
0x08001996 F3AF8000  NOP.W   
0x0800199A 9002      STR      r0,[sp,#0x08]
0x0800199C 4668      MOV      r0,sp
0x0800199E F7FEFBDF  BL.W     __ARM_argv_veneer (0x08000160)
20、在 __ARM_argv_veneer中
0x08000160 F001BC80  B.W      __ARM_get_argv (0x08001A64)it (0x08001A44)马上又跳转到另一个函数。又单纯的返回而已。
0x080019C2 4680      MOV      r8,r0
0x080019C4 F000F848  BL.W     __rt_locale (0x08001A58)
0x080019C8 2100      MOVS     r1,#0x00;最后又回到__rt_entry中。
0x080017D2 B40F      PUSH     {r0-r3}
0x080017D4 F000F93B  BL.W     _platform_post_lib_init (0x08001A4E)
0x080017D8 BC0F      POP      {r0-r3};最后的操作马上机会进入到主函数main中执行用户程序。

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /2 下一条