日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

__main代码分析

發布時間:2025/3/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 __main代码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

STM32啟動代碼主要是分配堆棧及設置向量表,然后跳轉到__main函數。

跳轉具體到代碼段部分如下:

[cpp]?view plain?copy
  • Reset_Handler???PROC??
  • ????????????????EXPORT??Reset_Handler?????????????[WEAK]??
  • ????????????????IMPORT??__main??
  • ????????????????LDR?????R0,?=?__main??
  • ????????????????BX??????R0??
  • ????????????????ENDP??
  • 當您看到__main函數時,估計應該有不少人認為這個是main函數的別名或是編譯之后的名字,否則在啟動代碼中再也無法找到和main相關的字眼了??墒聦嵤?#xff0c;__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這個函數來設置堆棧空間。

    總結

    以上是生活随笔為你收集整理的__main代码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。