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
總結
以上是生活随笔為你收集整理的MDK_main()代码执行过程分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32启动文件详解及SystemIn
- 下一篇: 3D数学 ---- 矩阵和线性变换