STM32 启动文件分析

STM32 启动文件分析

基于STM32F103VET6芯片的 startup_stm32f10x_hd.s 启动文件分析
在这里插入图片描述

  • 设置栈,将栈的大小Stack_Size设置为0x00004900(18688/1024=18KB),即局部变量不能大于18KB。(EQU等值指令,将0x00004900地址赋给标号Stack_Size。)
  • AREA 指令用于定义程序的不同区域,STACK表示栈区域,NOINIT表示该区域不需要进行初始化,READWRITE 表示该区域可读可写。ALIGN=3 表示该区域的起始地址需要按照 2^3 = 8 字节对齐。
  • Stack_Mem SPACE Stack_Size ;开辟一段大小为Stack_Size的内存空间作为栈。
  • __initial_sp表示程序的初始栈指针。栈通常从高地址向低地址生长。__initial_sp 定义为栈顶地址。程序启动时,编译器会使用 __initial_sp的值来初始化硬件的栈寄存器。

在这里插入图片描述

  • 设置堆,将堆的大小Heap_Size设置为0x00002400(9216/1024=9KB),堆用于动态分配内存。
  • AREA 定义HEAP堆区域,不需要初始化,可读可写,ALIGN=3 表示该区域的起始地址需要按照 2^3 = 8 字节对齐。
  • __heap_base 表示堆的起始地址。
  • Heap_Mem SPACE Heap_Size 开辟一段大小为Heap_Size的内存空间作为堆。
  • __heap_limit 堆空间结束地址。
  • PRESERVE8当前文件的堆栈按照8字节对齐,确保在运行程序时,堆栈数据能够正确地在内存中加载和存储。
  • THUMB表示后面指令兼容THUMB指令。THUMB是ARM以前的指令集,16位的,而现在Cortex-M系列都使用THUMB-2指令集,是32位的。
    在这里插入图片描述
  • AREA RESET, DATA, READONLY 表示定义一个只读数据段,数据段名称为RESET。(DATA表示数据段,用于存储全局变量和静态变量等可读写的数据。READONLY存储只读的数据,如常量字符串和只读变量等。这句话表示RESET数据段在程序执行期间可读写,在程序运行期间只读。)
  • EXPORT __Vectors 表示在程序中声明一个全局的标号__Vectors,该标号可在其他的文件中引用,中断向量表的入口地址。
  • EXPORT __Vectors_End 表示在程序中声明一个全局的标号__Vectors_End,中断向量表的结束地址。
  • EXPORT __Vectors_Size 在程序中声明一个全局的标号__Vectors_Size,中断向量表的大小。
    在这里插入图片描述
  • 建立中断向量表,DCD表示分配一个4字节的空间。首地址一定要是栈顶指针,Top of Stack,存放于FLASH中的0x8000000地址处,这部分是系统内部中断。
  • DCD指令:作用是开辟一段空间,其意义等价于 C 语言中的地址符 “&” 。中断向量表的建立类似于使用C语言定义了一个指针数组,其每一个成员都是一个函数指针,分别指向各个中断服务函数。
    在这里插入图片描述
  • 这部分是外部中断。
    在这里插入图片描述
  • __Vectors_End 中断向量表的结束地址
  • __Vectors_Size EQU __Vectors_End - __Vectors 中断向量表的大小
  • AREA |.text|, CODE, READONLY 定义只读代码段.text
    在这里插入图片描述
  • Reset_Handler 复位中断服务程序,PROC…ENDP结构表示程序的开始和结束。
  • EXPORT Reset_Handler [WEAK] 声明复位中断向量Reset_Handler为全局属性,外部文件就可以调用此复位中断服务。[WEAK]弱定义(Weak Definition),表示如果其他地方有Reset_Handler这个函数,用其他地方的Reset_Handler,如果没有,使用这里的Reset_Handler。
  • IMPORT 告诉编译器要使用的标号在其他源文件中定义,IMPORT __main,IMPORT SystemInit表示要调用__main和SystemInit两个函数。
  • LDR R0, =SystemInit 表示通过LDR将SystemInit地址给R0寄存区。(LDR 指令的作用是从指定的源地址读取数据,并将其加载到目标寄存器中。)
  • BLX 指令的作用是将当前指令的下一条指令的地址存储到链接寄存器(LR)中,并跳转到目标地址。这里会记下下一条指令的地址放入链接寄存器中,然后跳转到SystemInit地址执行,最后跳到链接寄存器地址继续执行。(BLX还会改变当前指令 THUMB—>ARM。)
  • LDR R0, =__main,将__main存储到R0,BX R0 表示跳转到刚刚R0存储值__main位置执行,并且最终会跳转到main(),进入C语言运行环境。(BX是无条件分支跳转指令,没有像BLX一样将下一条指令的地址存储到链接寄存器。跳转后就不会回来,BX也会改变当前指令THUMB—>ARM。)
    在这里插入图片描述
  • 这一段是异常处理程序,定义的都是弱函数,以NMI_Handler为例,如果程序其他地方没有NMI_Handler函数,会执行这里的函数,以确保程序的运行。
  • 这里只是给出基础的函数框架,具体的实现需要手动填充。可以在这里的弱函数里填充,也可以自己定义对应函数。一般,在stm32f10x_it.c文件中,可以填充这里同名的中断服务函数。也可以注释掉stm32f10x_it.c文件中的一些中断服务函数,在想要实现的文件中自己定义实现。
    在这里插入图片描述
    在这里插入图片描述
  • 这些是外围设备的中断处理函数,在使用对应中断事件时,需要在程序中编写处理函数来响应中断事件。
    在这里插入图片描述
  • 堆栈初始化,在上文中已经知道,中断向量表规定第一行必须是SP地址,第二行是复位中断入口地址,上电后,CPU首先就会读这两个值。上电时已经初始了SP,为什么这里又初始化堆栈?因为上电只是将_initial_sp值存入了SP寄存器,这只是一个栈顶指针,但堆的大小和栈的大小并没有初始化,所以在_main中要把在启动文件中定义好的值传给C库进行堆栈大小的初始化。
  • IF :DEF:__MICROLIB 如果使用Micro LIB微库(在keil的Target中可选择),将栈顶指针、堆起始地址、堆结束地址赋予全局属性供外部程序调用。
  • IMPORT __use_two_region_memory 定义全局标号
  • EXPORT __user_initial_stackheap 声明全局标号
  • __user_initial_stackheap 表示用户堆栈初始化程序入口
  • LDR R0, = Heap_Mem 加载堆的起始地址到寄存器 R0,
  • LDR R1, =(Stack_Mem + Stack_Size) 加载栈的结束地址到R1,
  • LDR R2, = (Heap_Mem + Heap_Size) 加载堆的结束地址到R2,
  • LDR R3, = Stack_Mem 加载栈的起始地址到寄存器 R3,
  • BX LR 返回到调用这个子程序的位置。
  • ALIGN用于在代码中插入一个对齐标记,以确保后续代码的对齐。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

fiddler弱网测试实践

准备工作 1、fiddler安装包 2、一部安卓手机 一、fiddler安装 安装fiddler到电脑上,傻瓜式安装即可 二、fiddler环境配置 三、手机端环境配置 1、获取电脑的IP地址:WindowsR,输入cmd弹出命令窗口,输入命令ipconfig 或者鼠标…

无mac电脑生成uniapp云打包私钥证书的攻略

uniapp顾名思义是一个跨平台的开发工具,大部分uniapp的开发者,其实并没有mac电脑来开发,但是生成ios的证书,官网的教程却是需要mac电脑的,那么有没有办法无需mac电脑即可生成uniapp云打包的私钥证书呢? 下…

虚幻学习笔记1—给UI添加动画

一、前言 本文所使用的虚幻版本为5.3.2,之前工作都是用unity,做这类效果用的最多的是一个DoTween的插件,在虚幻中都内置集成了这这种效果制作。 图1.1 UI动画 二、过程 1、首先,在诸如按钮、图像等可交互控件中选中,如…

vue项目通过HBuilder打包成apk,实现apk自动更新下载

vue 项目通过 HBuilder 打包成 apk,实现 apk 自动更新下载 1、vue 项目通过 HBuilder 打包成 apk vue 项目在终端执行 npm run build 打包成 dist 文件,生成的 dist 文件在 项目根目录下 在 HBuilder 中 新建一个项目 默认选择 5APP 的默认模板项目…

43.0BaseDao抽取dao公共父类

43.1. 回顾 1. 把数据库表中查询的结果封装到一个实体类中。 命名规则:类名和表名一致 类中属性和表的字段对应。 表中的一条记录对应实体的一个对象 多条记录→集合 43.2. 正文 目录 43.1. 回顾 43.2. 正文 43.3. 抽取dao公共父类。 43.4. 引入数据源 43.3. 抽取dao公共…

小米的算法部署岗对新手是真的友好

大家好啊,我是董董灿。 自从开始写一些AI行业的岗位介绍,就养成了一个习惯,在上下班的路上经常就会打开某聘瞧一瞧。 导致之前一年不看的某聘认为我要看机会换工作,疯狂给我推猎头,然后电话就进来了。 不堪骚扰的我…

EG20网口远程下载程序使用案例

EG20网口远程下载程序使用案例 前言:本文档主要说明了使用蓝蜂虚拟网络工具通过EG20网关的网口(LAN口)远程给PLC下载程序的步骤及其注意事项。使用蓝蜂虚拟网络工具,不仅支持程序的远程下载,同样支持程序的远程上传与…

11-30 SpringBoot

内嵌的tomcat tomcat的依赖 对于tomcat其实还是一个jar包 spring是一个IOC容器 tomcat的核心对象交给Spring容器 调用核心对象方法 启动Tomcat 1.添加依赖 tomcat-embed-core,叫做tomcat内嵌核心。就是这个东西把tomcat功能引入到了我们的程序中的 排除tomcat&a…

python爬取robomaster论坛数据,作为后端数据

一. 内容简介 python爬取robomaster论坛数据,作为后端数据 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3代码 三.主要流程 3.1 接口分析 # 接口分析 # 全部数据 # https://bbs.robomaster.com/forum.php?modforumdisplay&fid63 2…

一个软件测试练手项目——学生信息管理系统测试,卷起来啊

免费分享一个练手项目,学生信息管理系统,获取方式在文末 1.引言 1.1项目目的 软件测试是为了在软件投入生产性运行之前,尽可能多地发现软件的错误。该项目的目的是给学习软件测试的朋友练手用 1.2 项目背景 随着学校的规模不断扩大&…

处理机调度与作业调度

处理机调度 一个批处理型作业,从进入系统并驻留在外存的后备队列上开始,直至作业运行完毕,可能要经历如下的三级调度 高级调度 也称为作业调度、长程调度、接纳调度。调度对象是作业 主要功能: 挑选若干作业进入内存 为作业创建…

linux NAT网卡配置static

由于是内网,资料无法拷贝,借助参考资料,整理发出。 镜像安装 基本操作。 查看VM配置 图1,有几个信息。一个是NAT借用了网卡里的VMnet8适配器。 子网IP是从192.168.142.0 子网掩码255.255.255.255,对应下面配置的N…