上位机图像处理和嵌入式模块部署(f103 mcu中main入口函数误解)

news2024/12/24 2:20:33

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        学习stm32代码的时候,关于汇编文件,大家一般都会参考官方给出的汇编文件。通常情况下,不会自己去写汇编文件。特别是汇编文件的最后一行,大家都会把__main看成是直接进入main函数。后面通过反汇编,发现情况并不是这样的。我们编写代码,除了keil工程中的内容,还有MicroLib库,这一点常常被我们忽视。

1、之前的汇编代码

; Reset handler
Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  __main
                IMPORT  SystemInit
                LDR     R0, =SystemInit
                BLX     R0               
                LDR     R0, =__main
                BX      R0
                ENDP

        汇编代码这部分呢,大家一般都不会陌生,我们也通常都认为是__main直接跳转到了自定义的main函数。但是实际情况,我们可以通过反汇编来确认。

2、如何生成反汇编文件

        在项目的User tab配置中,添加这样的命令,就可以在project下面生成dis文件,

fromelf --text -a -c --output=Fire_F103VE.dis ../Output/Fire_F103VE.axf

        这样在最后的axf生成的同时,也能生成dis文件。如果需要生成bin文件,也是类似的做法。

fromelf --bin --output Fire_F103VE.bin ../Output/Fire_F103VE.axf

3、找到Reset_Handler位置

        首先我们找到Reset_Handler位置,

    __Vectors
        0x08000000:    20000410    ...     DCD    536871952
        0x08000004:    08000145    E...    DCD    134218053
        0x08000008:    08000d81    ....    DCD    134221185

        一般向量的第二个选项就是reset入口,不过mcu很奇怪,入口地址都要减去1才是正确的地址。也就是说,这里的Reset_Handler其实是08000144,

    Reset_Handler
        0x08000144:    4806        .H      LDR      r0,[pc,#24] ; [0x8000160] = 0x8000e17
        0x08000146:    4780        .G      BLX      r0
        0x08000148:    4806        .H      LDR      r0,[pc,#24] ; [0x8000164] = 0x8000131
        0x0800014a:    4700        .G      BX       r0

        我们发现了,这边pc最后跳转的地址是8000131,因为需要减去1,那就是8000130,

    _main_stk
        0x08000130:    f8dfd00c    ....    LDR      sp,__lit__00000000 ; [0x8000140] = 0x20000410
    .ARM.Collect$$$$00000004
    _main_scatterload
        0x08000134:    f000f82a    ..*.    BL       __scatterload ; 0x800018c

        这边执行不久,就跳转到了__scatterload,

    __scatterload
    __scatterload_rt2
        0x0800018c:    4c06        .L      LDR      r4,[pc,#24] ; [0x80001a8] = 0x8000ec4
        0x0800018e:    4d07        .M      LDR      r5,[pc,#28] ; [0x80001ac] = 0x8000ee4
        0x08000190:    e006        ..      B        0x80001a0 ; __scatterload + 20
        0x08000192:    68e0        .h      LDR      r0,[r4,#0xc]
        0x08000194:    f0400301    @...    ORR      r3,r0,#1
        0x08000198:    e8940007    ....    LDM      r4,{r0-r2}
        0x0800019c:    4798        .G      BLX      r3
        0x0800019e:    3410        .4      ADDS     r4,r4,#0x10
        0x080001a0:    42ac        .B      CMP      r4,r5
        0x080001a2:    d3f6        ..      BCC      0x8000192 ; __scatterload + 6
        0x080001a4:    f7ffffc8    ....    BL       __main_after_scatterload ; 0x8000138

        快结束的时候,又跳转到了__main_after_scatterload,

    __main_after_scatterload
    _main_clock
    _main_cpp_init
    _main_init
        0x08000138:    4800        .H      LDR      r0,[pc,#0] ; [0x800013c] = 0x8000e75
        0x0800013a:    4700        .G      BX       r0

        这边貌似要回到main函数了,看这里的地址是8000e75,那就是8000e74,

    i.main
    main
        0x08000e74:    bf00        ..      NOP      
        0x08000e76:    f7ffff9e    ....    BL       SystemClock_Config ; 0x8000db6
        0x08000e7a:    f7ffff2b    ..+.    BL       LED_GPIO_Config ; 0x8000cd4
        0x08000e7e:    e012        ..      B        0x8000ea6 ; main + 50
        0x08000e80:    2200        ."      MOVS     r2,#0
        0x08000e82:    f44f5100    O..Q    MOV      r1,#0x2000
        0x08000e86:    4808        .H      LDR      r0,[pc,#32] ; [0x8000ea8] = 0x40011000
        0x08000e88:    f7fffb4a    ..J.    BL       HAL_GPIO_WritePin ; 0x8000520
        0x08000e8c:    f44f707a    O.zp    MOV      r0,#0x3e8
        0x08000e90:    f7fff992    ....    BL       HAL_Delay ; 0x80001b8
        0x08000e94:    2201        ."      MOVS     r2,#1
        0x08000e96:    0351        Q.      LSLS     r1,r2,#13
        0x08000e98:    4803        .H      LDR      r0,[pc,#12] ; [0x8000ea8] = 0x40011000
        0x08000e9a:    f7fffb41    ..A.    BL       HAL_GPIO_WritePin ; 0x8000520
        0x08000e9e:    f44f707a    O.zp    MOV      r0,#0x3e8
        0x08000ea2:    f7fff989    ....    BL       HAL_Delay ; 0x80001b8
        0x08000ea6:    e7eb        ..      B        0x8000e80 ; main + 12

        看到上面的代码,大约可以验证到我们的猜测了。

4、总结

        之前在做linux soc芯片汇编文件编写的时候,中断初始化、bss初始化、sp初始化、已初始化全局变量copy、main函数跳转,这些都是基本的内容。后面自己看mcu代码的时候,却没有发现这部分内容,当时觉得很诧异,直到后来自己看了axf文件的反汇编内容之后,才晓得ide和背后的编译器帮我们做了很多事情。刚才说的这一切,都在main函数调用之前准备好了。但恰恰这一点,对于我们debug调试、分析和boot 加载研究很有帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1715551.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

决策树模型-预测用户是否购买某母婴产品

1,场景描述 假设我们是京东的数据分析师,负责分析母婴产品的购买行为。我们想预测用户是否会购买一款新上线的母婴产品。为了进行预测,我们将利用用户的历史购买数据、浏览行为和其他特征,通过决策树模型进行分析,并提…

全球市值最高的能源公司沙特阿美股份拟出售,筹集百亿美元

KlipC报道:据5月28日市场消息,沙特政府可能最快会在本周宣布拟出售国营石油公司沙特阿美股份,筹集100亿-200亿美元。 沙特阿美是世界最大的石油生产商,2019年在沙特证交所上市。沙特的经济高度依赖石油出口。此前,受石…

Vue2基本创建项目

简单版项目初始化 新建一个vue2 官网文档:介绍 — Vue.js 先确保下载了vue的脚手架 npm install -g vue-cli npm install -g vue/cli --force vue -V 创建项目 vue create 自己起个名字 选择自己选择特性 选择: Babel:他可以将我们写…

算法的时间复杂度(详解)

前言: 算法(Algorithm):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为 输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果 一、算法效率 1.1 如何衡量一个算法的好坏 如何衡…

人工智能初识

🌞欢迎来到人工智能基础的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 📆首发时间:🌹2024年5月1…

小程序内的分包与数据共享

一:数据共享 小程序内的数据共享和vue当中不一样,vue当中的vue实例可以使得所有的组件都能this.store 但是小程序它只有page对象,和组件实例对象.对于vue而言,vue实例可以使得添加的组件都有. 但是page对象页面对象,不能使得页面内部有.只能使得这个页面内能访问.vue实例,会…

微信聊天内容怎么监控? | 三款可以监控电脑微信聊天记录的软件大盘点

你是否听说过监控微信呢? 有时出于特定需求,比如家长对孩子上网行为的关心,或者企业对员工工作效率的监控,可能需要了解某些情况下的微信聊天记录。 但请注意,任何未经授权的监控行为都是违法的,并且可能…

使用C语言实现学生信息管理系统

前言 在我们实现学生信息管理系统的过程中,我们几乎会使用到C语言最常用最重要的知识,对于刚学习完C语言的同学来说是一次很好的巩固机会,其中还牵扯到数据结果中链表的插入和删除内容。 实现学生信息管理系统 文件的创建与使用 对于要实现…

【国产中颖】SH79F9202U单片机驱动LCD段码液晶学习笔记

1. 引言 因新公司之前液晶数显表产品单片机一直用的是 C51单片机(SH79F9202U9),本人之前没有接触过这款单片机,为了维护老产品不得不重新研究研究这款单片机。 10位ADC LCD的增强型8051微控制器 SH79F9202是一种高速高效率8051可兼容单片机。在同样振…

5G工厂长啥样

5G工厂是一种新型的工业互联网基础设施,利用5G为代表的新一代信息通信技术集成,打造新型工业互联网基础设施。在5G工厂中,自动化和智能化设备广泛使用,高度互联的工厂网络得以实现,远程监控和管理成为可能,…

鸿蒙应用模型:【Stage模型开发】概述

Stage模型开发概述 基本概念 下图展示了Stage模型中的基本概念。 图1 Stage模型概念图 [AbilityStage] 每个Entry类型或者Feature类型的HAP在运行期都有一个AbilityStage类实例,当HAP中的代码首次被加载到进程中的时候,系统会先创建AbilityStage实例…

微信网页版登录插件v1.1.1

说到如今的微信客户端,大家肯定会有很多提不完的意见或者建议。比如这几年体积越来越大,如果使用频率比较高,那占用空间就更离谱了。系统迷见过很多人电脑C盘空间爆满,都是由于微信PC版造成的。 而且,它还加了很多乱七…

【第8章】SpringBoot之单元测试

文章目录 前言一、准备1. 引入库2. 目录结构 二、测试代码1. SpringBoot3ApplicationTests2.测试结果 总结 前言 单元测试是SpringBoot项目的一大利器&#xff0c;在SpringBoot我们可以很轻松地测试我们的接口。 一、准备 1. 引入库 <dependency><groupId>org.s…

【JS基础知识07】函数

一&#xff1a;函数是什么以及函数作用 1 函数是什么 函数是经过封装、调用后&#xff0c;能够完成特定任务的代码块 2 函数的作用 仅需“函数名(实参)”就可以调用函数&#xff0c;起到精简代码&#xff0c;提高开发效率的作用 二&#xff1a;函数使用 1 语法规则&#…

Android 控件保持宽高比得几种方式

文章目录 Android 控件保持宽高比得几种方式adjustViewBounds百分比布局ConstraintLayout自定义View Android 控件保持宽高比得几种方式 adjustViewBounds 仅适用于 ImageView&#xff0c;保持横竖比。 <ImageViewandroid:layout_width"match_parent"android:l…

【使用ChatGPT构建应用程序】应用程序开发概述:1. 管理秘钥、2. 数据安全、3. 与应用程序解耦、4. 注意提示语的注入攻击

文章目录 一. 首先注意的两个方面1. 管理API密钥1.1. 用户提供API密钥1.2. 你自己提供API密钥 2. 数据安全和数据隐私 二. 软件架构设计原则&#xff1a;与应用程序解耦三. 注意LLM提示语的注入攻击1. 分析输入和输出2. 监控和审计3. 其他要注意的注入情况 在了解了ChatGPT的文…

SheetJS V0.17.5 导入 Excel 异常修复 Invalid HTML:could not find<table>

导入 Excel 提示错误&#xff1a;Invalid HTML:could not find<table> 检查源代码 发现 table 属性有回车符 Overview: https://docs.sheetjs.com/docs/ Source: https://git.sheetjs.com/sheetjs/sheetjs/issues The public-facing websites of SheetJS: sheetjs.com…

Linux静态库、共享动态库介绍、制作及使用

参考学习&#xff1a;Linux下的各种文件 、动态库基本原理和使用方法&#xff0c;-fPIC选项的来龙去脉 、Linux静态库和动态库分析 文章写作参考&#xff1a;Linux共享库、静态库、动态库详解 - sunsky303 - 博客园 (cnblogs.com) 一.Linux共享库、静态库、动态库详解 使用G…

2021CSP-J普及组复赛-第一题:分糖果

2021CSP-J普及组复赛 第一题&#xff1a; 题目&#xff1a; 输入&#xff1a; 7 16 23输出&#xff1a; 6思路&#xff1a; 这是一个简单的思考题&#xff0c;没有用到重要的算法 ①简单的思路即暴力方法就是利用for循环从L 到 R 遍历求出其中最大的奖励值&#xff0c;由于R…

全程曝光 计算机领域顶会投稿后会经历哪些关键环节?

会议之眼 快讯 亲爱的计算机领域大牛们&#xff0c;当你挥洒汗水&#xff0c;精心打磨一篇科研论文&#xff0c;终于怀着激动的心情投稿至顶会——&#xff08;如&#xff08;ACM MM 、ACL、AAAI&#xff09;时&#xff0c;你是否想知道接下来这篇论文会经历怎样的旅程&#x…