單片機啟動文件——數據段重定位,BSS段清零

目錄

    • 重定位概念的引入
      • 一、數據段重定位
        • 1.作用:
        • 2.目的:
        • 3.自己模擬代碼
      • 二、BSS段清零
        • 1.作用:
        • 2.目的:
        • 3.自己模擬代碼
      • 三,實現原理

重定位概念的引入

單片機中內存段的詳細介紹
在單片機中內存分為了很多不同的區域,在上面的文章中可以看到,flash與RAM中有兩段空間的信息在flash與RAM都保持了,分別是RWdata段與bss段,在啟動文件中對這兩塊區域分別進行了數據段重定位與BSS段清零,而對應的代碼是由編譯器根據散列文件自動生成的,我們看不到,但是我們可以不讓編譯器自動生成自己進行數據段重定位與BSS段清零

數據段重定位與BSS段清零對應的代碼是由編譯器根據散列文件自動生成的,我們看不到,我們可以通過反匯編文件以及Debug時的反匯編窗口看到編譯器給我們生成的代碼如何讓keil編譯生成bin文件與反匯編文件?,同時我們可以不讓編譯器自動生成自己進行數據段重定位與BSS段清零
操作方法就是
1.不使用main的函數名,使用其它函數名
在這里插入圖片描述
在這里插入圖片描述

一、數據段重定位

1.作用:
  • 將.data段從非易失性存儲器(如Flash/ROM)復制到易失性存儲器(RAM)中的目標位置。

  • 鏈接器在編譯鏈接階段,會將已初始化的全局變量和靜態變量放入.data段,并將它們的初始值存儲在Flash中。

  • 但是程序運行時,這些變量必須位于RAM中才能被修改。

  • 啟動文件負責將存儲在Flash中的初始值數據“搬運”到RAM中對應變量的地址處。

2.目的:
  • 確保初始化變量擁有正確的初始值:如果.data段沒有從Flash復制到RAM,那么所有初始化為非零值的全局變量和靜態變量在程序啟動時將處于未定義狀態(RAM上電后的值是隨機的),而不是程序員設定的初始值。這會導致程序行為完全不可預測。

  • 滿足C/C++語言規范要求:C/C++標準規定全局變量和靜態變量必須在程序啟動時完成初始化(如果有初始值)。重定位是實現這一語言要求的底層機制。

  • 實現變量的可寫性:Flash通常是只讀的(在運行時),而變量需要被程序讀寫。將初始值復制到RAM中是變量可寫的先決條件。

3.自己模擬代碼
/*啟動文件模擬過程代碼*/IMPORT |Image$$RW_IRAM1$$Base|IMPORT |Image$$RW_IRAM1$$Length|IMPORT |Load$$RW_IRAM1$$Base|LDR R0, = |Image$$RW_IRAM1$$Base|    ; DESTLDR R1, = |Load$$RW_IRAM1$$Base|     ; SORUCELDR R2, = |Image$$RW_IRAM1$$Length|  ; LENGTH //根據ARM架構AAPCS法則模擬函數參數BL My_Copy	 
/*C語言實現拷貝邏輯*/				 
void My_Copy(char* const Destination,char* const Soruce,int Size)
{int i = 0;for(;i < Size;i ++){Destination[i] = Soruce[i];}return;
}

二、BSS段清零

1.作用:
  • 將.bss段在RAM中對應的內存區域全部填充為0。

  • 鏈接器將未初始化或顯式初始化為0的全局變量和靜態變量放入.bss段。.bss段在程序映像(存儲在Flash中)中不占用實際存儲空間,它只記錄需要在RAM中預留多少空間以及起始地址。

  • 啟動代碼需要找到.bss段在RAM中的起始地址和長度,然后將這塊內存區域清零。

2.目的:
  • 確保未初始化的變量從0開始:C/C++標準規定未顯式初始化的全局變量和靜態變量在程序啟動時必須被初始化為0(對于基本類型是0,對于指針是NULL)。如果不清零.bss段,這些變量在啟動時將包含RAM上電后的隨機垃圾值,導致程序行為不可預測,尤其是指針變量可能指向非法地址。

  • 節省Flash存儲空間:由于.bss段中的變量初始值都是0,沒有必要在Flash中存儲一大串0值。啟動時直接清零對應的RAM區域是更高效的方法(空間換時間)。

  • 滿足語言規范要求:與.data段重定位一樣,BSS清零是實現C/C++語言對未初始化/零初始化全局變量和靜態變量初始化要求的底層機制。

3.自己模擬代碼
/*啟動文件模擬過程代碼*/IMPORT |Image$$RW_IRAM1$$ZI$$Base|IMPORT |Image$$RW_IRAM1$$ZI$$Length|	LDR R0, = |Image$$RW_IRAM1$$ZI$$Base|   ; DESTLDR R1, = 0                             ; SORUCE LDR R2, = |Image$$RW_IRAM1$$ZI$$Length| ; LENGTH BL My_Zero_Init	//根據ARM架構AAPCS法則模擬函數參數BL My_Zero_Init
/*C語言實現清零邏輯*/				 
void My_Zero_Init(char* const Destination,int Soruce,int Size)
{int i = 0;for(;i < Size;i ++){Destination[i] = Soruce;}return;
}

三,實現原理

C語言-》編譯器-》機器碼(匯編就是機器碼的注釋)
展開能力,C語言與匯編的后溝就是編譯器,C語言是編程工具,匯編語言是結果
判斷結果是否符合預期?學會看反匯編
如何控制結果符合預期?學會一定的C語言語法以及編譯器的工作特性

針對keil平臺,控制編譯器的方法就是分散加載文件
我們可以通過分散加載文件的語法來控制代碼函數變量的鏈接地址
理論上也可以控制加載地址針對使用燒錄器來說因為燒錄器使用的是hex文件包含程序燒錄的地址信息,但是一般來說程序編譯后使用bin二進制文件這個文件使用特定的燒錄工具,燒錄的是純機器碼即代碼指令不包含代碼加載地址信息。
分散加載的語法可以參考分散加載文件與attribute關鍵字使用說明
同時分散加載文件中也包含一些符號信息,我們在代碼中可以使用特定的語法來引入這些符號的值,RW-data段的加載地址大小,搬運的目的地址,同理bss段數據也是同理。
導入符號的方法有

/*匯編文件使用*/IMPORT |Image$$ER_IROM1$$Base|IMPORT |Image$$ER_IROM1$$Length|IMPORT |Load$$ER_IROM1$$Base|IMPORT |Image$$RW_IRAM1$$Base|IMPORT |Image$$RW_IRAM1$$Length|IMPORT |Load$$RW_IRAM1$$Base|IMPORT |Image$$RW_IRAM1$$ZI$$Base|IMPORT |Image$$RW_IRAM1$$ZI$$Length|	
/*C語言文件使用*/extern int Image$$ER_IROM1$$Base;extern int Image$$ER_IROM1$$Length;extern int Load$$ER_IROM1$$Base;extern int Image$$RW_IRAM1$$Base;extern int Image$$RW_IRAM1$$Length;extern int Load$$RW_IRAM1$$Base;extern int Image$$RW_IRAM1$$ZI$$Base;extern int Image$$RW_IRAM1$$ZI$$Length;	extern int Image$$ER_IROM1$$Base[];extern int Image$$ER_IROM1$$Length[];extern int Load$$ER_IROM1$$Base[];extern int Image$$RW_IRAM1$$Base[];extern int Image$$RW_IRAM1$$Length[];extern int Load$$RW_IRAM1$$Base[];extern int Image$$RW_IRAM1$$ZI$$Base[];extern int Image$$RW_IRAM1$$ZI$$Length[];	extern int * Image$$ER_IROM1$$Base;extern int * Image$$ER_IROM1$$Length;extern int * Load$$ER_IROM1$$Base;extern int * Image$$RW_IRAM1$$Base;extern int * Image$$RW_IRAM1$$Length;extern int * Load$$RW_IRAM1$$Base;extern int * Image$$RW_IRAM1$$ZI$$Base;extern int * Image$$RW_IRAM1$$ZI$$Length;	

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96501.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96501.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96501.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

QT(3)

四、基本組件1. Designer設計師&#xff08;掌握&#xff09;Qt Designer 是 Qt 提供的可視化界面設計工具&#xff0c;支持通過拖拽組件快速構建 GUI 界面&#xff0c;生成的界面文件以 .ui格式保存&#xff08;基于 XML 的標簽語言&#xff09;。??核心功能??&#xff1a…

常用注解:@PostMapping、@RequestBody、@Autowired、@Service、@Mapper

1. PostMapping作用&#xff1a;將方法綁定到 HTTP POST 請求的特定路徑上用法&#xff1a;PostMapping("/login") // 綁定到 POST /login PostMapping("/employees") // 綁定到 POST /employees PostMapping("/users/{id}") …

SoC日志管理

目錄 一、汽車控制器中日志的核心類型 二、日志管理的核心環節與策略 1. 日志采集:確保“全面且不冗余” 2. 日志存儲:平衡“可靠性”與“存儲成本” 3. 日志安全:防止“篡改與泄露” 4. 日志生命周期:符合“法規與成本” 5. 日志工具與實現 三、汽車場景的特殊約束與應對 …

橫評五款開源多智能體框架,AI高手都在用哪個?下一款Manus、Cursor、Devin,誰能撐起來?

Agent 成為共識的速度非常快。但今年 Agent 的真正轉折點在于&#xff1a;多智能體。 從科研自動化到任務編排&#xff0c;從自動開淘寶店到 Vibe 一切&#xff0c;從 AI 瀏覽器到今天的 ChatGPT Agent&#xff0c;一切都是多智能體的味道。 但要真正搭建一個多智能體&#x…

GitHub每日最火火火項目(9.10)

1. Physical-Intelligence / openpi 項目名稱&#xff1a;openpi項目介紹&#xff1a;基于 Python 開發&#xff0c;聚焦于物理智能領域&#xff0c;為相關研究與應用提供支持。Python 在科學計算、人工智能等領域有著廣泛且成熟的生態&#xff0c;借助其豐富的庫&#xff08;如…

2025年滲透測試面試題總結-61(題目+回答)

安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 2. 提交過什么漏洞 3. 常用漏洞掃描工具 4. OWASP TOP 10 2021核心變化 5. MySQL寫WebShell權限要求 6.…

高可用消息隊列線程池設計與實現:從源碼解析到最佳實踐

前言在現代分布式系統中&#xff0c;消息隊列處理是核心組件之一。今天我們將深入解析一個高性能、高可用的消息隊列線程池實現——FindMessageQueue&#xff0c;并探討如何將其優化應用于實際項目中。一、核心架構設計1.1 整體架構圖┌───────────────────…

Android App瘦身方法介紹

第一章 安裝包構成深度剖析1.1 APK文件結構解剖APK文件本質是一個ZIP壓縮包&#xff0c;通過unzip -l app.apk命令可查看其內部結構&#xff1a;Archive: app.apkLength Method Size Cmpr Date Time CRC-32 Name -------- ------ ------- ---- ---------- -…

深入淺出遷移學習:從理論到實踐

1. 引言&#xff1a;為什么需要遷移學習&#xff1f;在深度學習爆發的這十年里&#xff0c;我們見證了模型性能的飛速提升 ——ResNet 在圖像分類上突破人類視覺極限&#xff0c;BERT 在 NLP 任務上刷新基準&#xff0c;GPT 系列更是開啟了大語言模型時代。但這些亮眼成果的背后…

嵌入式人別再瞎折騰了!這8個開源項目,解決按鍵/隊列/物聯網所有痛點,小白也能抄作業

嵌入式人別再瞎折騰了&#xff01;這8個開源項目&#xff0c;解決按鍵/隊列/物聯網所有痛點&#xff0c;小白也能抄作業 你是不是也有過這樣的崩潰時刻&#xff1a;想做個按鍵控制&#xff0c;結果長按、連擊、組合鍵的邏輯寫了200行if-else&#xff0c;最后還時不時串鍵&#…

C++篇(7)string類的模擬實現

一、string的成員變量string和數據結構中的順序表類似&#xff0c;本質上可以理解成字符順序表&#xff0c;其成員變量仍然是_str&#xff0c;_size和_capacity。但是&#xff0c;C標準庫里面也有一個string&#xff0c;和我們要自己實現的string類沖突了&#xff0c;該如何解決…

【直接套模板】如何用 Web of Science 精準檢索文獻?

在文獻檢索的時候遇到一些問題&#xff0c;單獨使用關鍵詞檢索出來的文章數量太多&#xff0c;如果是多加一些限定詞&#xff0c;又什么都檢索不到&#xff1a;比如我明明知道某篇論文已經發表&#xff0c;但在 Web of Science (WoS) 里卻檢索不到。這其實和檢索式的寫法密切相…

HTTP 協議:從原理到應用的深度剖析

一、什么是HTTP協議&#xff1f;HTTP協議&#xff0c;全稱 Hyper Text Transfer Protocol&#xff08;超?本傳輸協議&#xff09;的縮寫&#xff0c;是?于服務器與客戶端瀏覽器之間傳輸超?本數據&#xff08;?字、圖?、視頻、?頻&#xff09;的應?層協議。它規定了客戶端…

【算法--鏈表】138.隨機鏈表的復制--通俗講解

算法通俗講解推薦閱讀 【算法–鏈表】83.刪除排序鏈表中的重復元素–通俗講解 【算法–鏈表】刪除排序鏈表中的重復元素 II–通俗講解 【算法–鏈表】86.分割鏈表–通俗講解 【算法】92.翻轉鏈表Ⅱ–通俗講解 【算法–鏈表】109.有序鏈表轉換二叉搜索樹–通俗講解 【算法–鏈表…

為什么現在企業注重數據可視化?一文講清可視化數據圖表怎么做

目錄 一、企業注重數據可視化的原因 1.提升數據理解效率 2.發現數據中的規律和趨勢 3.促進企業內部溝通與協作 4.增強決策的科學性 5.提升企業競爭力 二、可視化數據圖表的基本概念 1.常見的可視化圖表類型 2.可視化圖表的構成要素 3.可視化圖表的設計原則 三、制作…

Cursor 輔助開發:快速搭建 Flask + Vue 全棧 Demo 的實戰記錄

Cursor 輔助開發&#xff1a;快速搭建 Flask Vue 全棧 Demo 的實戰記錄 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般絢爛的技術棧中&#xff0c;我是那個永不停歇的色彩收集者。 &#x1f98b; 每一個優化都是我培育的花朵&#xff0c;每一個…

實戰:用 Python 搭建 MCP 服務 —— 模型上下文協議(Model Context Protocol)應用指南

&#x1f4cc; 實戰&#xff1a;用 Python 搭建 MCP 服務 —— 模型上下文協議&#xff08;Model Context Protocol&#xff09;應用指南 標簽&#xff1a;#MCP #AI工程化 #Python #LLM上下文管理 #Agent架構&#x1f3af; 引言&#xff1a;為什么需要 MCP&#xff1f; 在構建大…

宋紅康 JVM 筆記 Day16|垃圾回收相關概念

一、今日視頻區間 P154-P168 二、一句話總結 System.gc()的理解&#xff1b;內存溢出與內存泄漏&#xff1b;Stop The World;垃圾回收的并行與并發&#xff1b;安全點與安全區域&#xff1b;再談引用&#xff1a;強引用&#xff1b;再談引用&#xff1a;軟引用&#xff1b;再談…

OpenCV 高階 圖像金字塔 用法解析及案例實現

目錄 一、什么是圖像金字塔&#xff1f; 二、圖像金字塔的核心作用 三、圖像金字塔的核心操作&#xff1a;上下采樣 3.1 向下采樣&#xff08; pyrDown &#xff09;&#xff1a;從高分辨率到低分辨率 1&#xff09;原理與步驟 2&#xff09;關鍵注意事項 3&#xff09;…

【ARMv7】系統復位上電后的程序執行過程

引子&#xff1a;對于ARMv7-M系列SOC來說&#xff0c;上電后程序復位執行的過程相對來說比較簡單&#xff0c;因為絕大部分芯片&#xff0c;都是XIP&#xff08;eXecute In Place&#xff0c;就地執行&#xff09;模式執行程序&#xff0c;不需要通過BooROM->PL(preloader)-…