二、步骤续
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条评论)
登录后参与讨论