【Bootloader學習理解----跳轉優化異常】

筆者接著來介紹一下Bootloader的跳轉代碼以及優化

1、跳轉代碼理解

跳轉代碼可能要涉及到芯片架構的知識,要跳轉到對應的位置,還要設置相關的SP 堆棧指針,具體可以參考筆者這篇文章BootLoader的理解與實現。
STM32的跳轉代碼如下所示:

u32 ApplicationAddress = 0x08008000;  //app 地址 
typedef  void (*pFunction)(void);     //函數指針
void Jump_Used_Main(void)
{printf("\r\nboot2-------- Jump APP --------- \r\n");/*	判斷棧頂 是否位于 0x20000000  128K 	  */if (  ((*(__IO uint32_t*)ApplicationAddress) >= 0x20000000) &&((*(__IO uint32_t*)ApplicationAddress) <= 0x20010000)){ 	JumpAddress = *(__IO uint32_t*) (ApplicationAddress +4);Jump_To_Application = (pFunction) JumpAddress;/*close the interrupt*/_disable_interrupr();__set_MSP(*(__IO uint32_t*) ApplicationAddress);Jump_To_Application();}else{			while(1){printf("\r\nboot2  error\r\n");}}
}

可以看到__set_MSP(* (__IO uint32_t *) ApplicationAddress);這行代碼中,在取地址里面的內容時,增加了__IO的選項,

#define __IO volatile

保證是從內存里面讀出來的SP棧指針的數據,然后設置到MSP,否則可能導致SP設置錯誤,程序跑飛。

2、跳轉代碼編譯優化

筆者在實際開發的過程中,遇到了一個跳轉過去就崩掉的情況,單步調試,發現到Set_MSP就崩掉了,很是奇怪,通過匯編一查看,就很明顯了。

  • NXP LPC的單片機,
  • arm-noen-eabi-gcc的編譯器。
typedef struct addr_manager_struct
{xxxxxxx;u32 image_load_addr;u32 image_exec_addr;
}addr_manager_t;
u8 main_jump(addr_manager_t* info)
{u32 *image_addr = (u32*)info->image_load_addr;u32 *sp = (u32*) image_addr [0];u32 *jump = (u32*) image_addr [1];disable_interrupt();set_msp((u32)sp);(*jump)();return 0;
}

在這里插入圖片描述

  • 上述在設置完SP之后,放到r2寄存器里面,
  • 然后獲取jump地址,放到r3里面,
  • 之后禁止中斷修改了r2,然后禁止中斷
  • 然后就把r2傳到SP里面,
  • 造成跑飛,可能是一個不存在的地址

有人說sp設置的時候需要加volatile,即使改成下面的函數,也沒用效果

void jump_main(addr_manager_t* info)
{u32 *image_addr = (u32*)info->image_load_addr;u32 *sp = (u32*) image_addr [0];u32 *jump = (u32*) image_addr [1];disable_interrupt();set_msp((volatile u32)sp);(*jump)();
}

在這里插入圖片描述
接著再繼續改,直

  • 接通過Image指針取內容,然后去獲取到SP值,然后就可以了,
  • 看來是禁止中斷的這個函數所影響,
  • 禁止中斷如果不報存返回值,則不會對SP的值產生影響
void jump_main(addr_manager_t* info)
{u32 *image_addr = (u32*)info->image_load_addr;u32 *sp = (u32*) image_addr [0];u32 *jump = (u32*) image_addr [1];disable_interrupt();set_msp(*((volatile u32*)image_addr));(*jump)();
}

在這里插入圖片描述
接著我們再嘗試一種方法,就是將禁止中斷函數移動位置,看一下情況,發現也是可以的。

void jump_main(addr_manager_t* info)
{disable_interrupt();u32 *image_addr = (u32*)info->image_load_addr;u32 *sp = (u32*) image_addr [0];u32 *jump = (u32*) image_addr [1];set_msp((u32)sp);(*jump)();
}

在這里插入圖片描述
然后我們看一下set sp的匯編函數,也并沒有指明操作的寄存器,很可能是GCC編譯器優化的bug。

inline void set_sp(u32 sp_value)
{asm volatile ("msr msp, %0" : "=r"(sp_value))
}

然后我們再看看armcc編譯器的結果,沒有任何問題。

  • armcc對于禁止中斷的返回值沒有處理,
  • 而GCC處理了然后導致了問題(將其中斷保存值填到r2里面,然后r2的sp值被覆蓋),
  • 其實應用層如果沒有對返回值進行處理,即使函數有返回值,編譯器優化會將其處理掉。顯然GCC的編譯器優化做的還是差一點。

在這里插入圖片描述

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

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

相關文章

ClickHouse為何如此之快

針對ClickHose為什么很快的問題&#xff0c;基于對ClickHouse的基礎概念之上&#xff0c;一般會回答是因為是列式存儲數據庫&#xff0c;同時也會說是使用了向量化引擎&#xff0c;所以快。上面兩方面的解釋也都能夠站得住腳&#xff0c;但是依然不能夠解釋真正核心的原因。因為…

AI:101-基于深度學習的航空影像中建筑物識別

?? 本文選自專欄:人工智能領域200例教程專欄 從基礎到實踐,深入學習。無論你是初學者還是經驗豐富的老手,對于本專欄案例和項目實踐都有參考學習意義。 ??? 每一個案例都附帶有在本地跑過的核心代碼,詳細講解供大家學習,希望可以幫到大家。歡迎訂閱支持,正在不斷更新…

2023_刷題_二叉樹

文章目錄 書leixingleixing 書 leixing leixing

基于以太坊的智能合約開發Solidity(基礎篇)

參考教程&#xff1a;基于以太坊的智能合約開發教程【Solidity】_嗶哩嗶哩_bilibili 1、第一個程序——Helloworld&#xff1a; //聲明版本號&#xff08;程序中的版本號要和編譯器版本號一致&#xff09; pragma solidity ^0.5.17; //合約 contract HelloWorld {//合約屬性變…

Python軸承故障診斷 (四)基于EMD-CNN的故障分類

目錄 前言 1 經驗模態分解EMD的Python示例 2 軸承故障數據的預處理 2.1 導入數據 2.2 制作數據集和對應標簽 2.3 故障數據的EMD分解可視化 2.4 故障數據的EMD分解預處理 3 基于EMD-CNN的軸承故障診斷分類 3.1 訓練數據、測試數據分組&#xff0c;數據分batch 3.2 定義…

D : DS查找——折半查找求平方根

Description 假定輸入y是整數&#xff0c;我們用折半查找來找這個平方根。在從0到y之間必定有一個取值是y的平方根&#xff0c;如果我們查找的數x比y的平方根小&#xff0c;則x2<y&#xff0c;如果我們查找的數x比y的平方根大&#xff0c;則x2>y&#xff0c;我們可以據此…

stu05-前端的幾種常用開發工具

前端的開發工具有很多&#xff0c;可以說有幾十種&#xff0c;包括記事本都可以作為前端的開發工具。下面推薦的是常用的幾種前端開發工具。 1.DCloud HBuilder&#xff08;輕量級&#xff09; HBuilder是DCloud&#xff08;數字天堂&#xff09;推出的一款支持HTML5的web開發…

硬件開發筆記(十四):RK3568底板電路LVDS模塊、MIPI模塊電路分析、LVDS硬件接口、MIPI硬件接口詳解

若該文為原創文章&#xff0c;轉載請注明原文出處 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/134634186 紅胖子網絡科技博文大全&#xff1a;開發技術集合&#xff08;包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機、軟硬…

linux 關于$-的解釋(帖子搜索合集)

在學習Linux的時候&#xff0c;今天遇到了$-&#xff0c;什么意思呢&#xff1f;網上搜索了一些帖子&#xff1a; 帖子1&#xff1a; linux命令 $- 是什么意思 $- 是什么意思&#xff1f;有什么用&#xff1f;可以判斷什么交互式shell&#xff1f; $-記錄著當前設置的shell…

軟考高級備考-系統架構師(機考后新版教材的備考過程與資料分享)

軟考高級-系統架構設計師 考試復盤1.考試結果2.備考計劃3.個人心得 資料分享 考試復盤 1.考試結果 三科壓線過&#xff0c;真是太太太太太太太幸運了。上天對我如此眷顧&#xff0c;那不得不分享下我的備考過程以及一些備考資料&#xff0c;幫助更多小伙伴通過考試。 2.備考…

time模塊(python)

一.sleep休眠 [rootrhel8 day04]# vim demo01_time.py import time def banzhuan():print("搬磚")time.sleep(3.5) #讓程序休眠3.5秒print("結束")banzhuan()[rootrhel8 day04]# python3 demo01_time.py 搬磚 結束運行時&#xff0c;會發現程序中間暫停…

【3DsMax】制作簡單的骨骼動畫

效果 步驟 首先準備4個板子模型展開放置好 添加一個4段的骨骼 選中其中的一塊板子添加蒙皮命令 在蒙皮的參數面板中&#xff0c;設置每塊板子對應哪塊骨骼 設置好后你可以發現此時就已經可以通過骨骼來控制模型了 接下來就可以制作動畫 點擊左下角“時間配置”按鈕 設置一下動…

HarmonyOS--ArkTS(1)--基本語法(1)

目錄 基本語法概述 聲明式UI描述 自定義組件 創建自定義組件 自定義組件的結構--struct &#xff0c;Component&#xff0c;build()函數 生命周期 基本語法概述 裝飾器&#xff1a; 用于裝飾類、結構、方法以及變量&#xff0c;并賦予其特殊的含義。如上述示例中Entry、C…

VSCode安裝與使用

VS Code 安裝及使用 1、下載 進入VS Code官網&#xff1a;地址&#xff0c;點擊 DownLoad for Windows下載windows版本 注&#xff1a; Stable&#xff1a;穩定版Insiders&#xff1a;內測版 2、安裝 雙擊安裝包&#xff0c;選擇我同意此協議&#xff0c;再點擊下一步 選擇你…

SQL Server查詢計劃(Query Plan)——SQL處理過程

6. 查詢計劃(Query Plan) 6.1. SQL處理過程 就SQL語句的處理過程而言,各關系庫間大同小異,尤其是商業庫之間實現機制和細節差別更小些,其功能及性能支持方面也更加強大和完善。SQL Server作為商業庫中的后起之秀,作為SQL語句處理過程的主要支撐和保障,其優化器及相關機…

【Vulnhub 靶場】【hacksudo: ProximaCentauri】【簡單 - 中等】【20210608】

1、環境介紹 靶場介紹&#xff1a;https://www.vulnhub.com/entry/hacksudo-proximacentauri,709/ 靶場下載&#xff1a;https://download.vulnhub.com/hacksudo/hacksudo-ProximaCentauri.zip 靶場難度&#xff1a;簡單 - 中等 發布日期&#xff1a;2021年06月08日 文件大小&…

第9節:Vue3 指令

如何在UniApp中使用Vue3的指令&#xff1a; <template> <view> <!-- 使用指令 --> <text v-show"isVisible" click"toggleVisibility">點擊隱藏/顯示</text> <button v-on:click"incrementCount">點擊…

【LeetCode:70. 爬樓梯 | 遞歸 -> 記憶化搜索 -> DP】

&#x1f680; 算法題 &#x1f680; &#x1f332; 算法刷題專欄 | 面試必備算法 | 面試高頻算法 &#x1f340; &#x1f332; 越難的東西,越要努力堅持&#xff0c;因為它具有很高的價值&#xff0c;算法就是這樣? &#x1f332; 作者簡介&#xff1a;碩風和煒&#xff0c;…

【圖片版】計算機組成原理考前復習題【第3章 存儲系統-2(Cache)】

目錄 前言 考前復習題&#xff08;必記&#xff09; 結尾 前言 在計算機組成原理的學習過程中&#xff0c;我們深入探索了計算機系統概述這一重要領域。計算機系統作為現代科技的核心&#xff0c;是整個計算機科學的基石。我們將學到的知識與理論轉化為了能夠解決現實問題…

web api性能測試使用wrk

web api性能測試 這邊簡單的給出shell腳本 注意先安裝&#xff1a;wrk和gnuplot #!/bin/bash# Copyright 2020 Lingfei Kong <colin404foxmail.com>. All rights reserved. # Use of this source code is governed by a MIT style # license that can be found in the…