STM32启动文件分析(startup_stm32f10x_md.s)

2023-11-04

一般而言,系统上电后第一个执行的是由汇编所编写的启动文件,其主要工作为一下五部分

  • 初始化堆栈指针SP=_initial_sp
  • 初始化PC指针,令其=Reset_Handler
  • 初始化中断向量表
  • 配置系统时钟
  • 调用C库函数_main初始化用户堆栈,从而最终调用main函数进入C的世界

初始化堆栈

初始化栈指针(SP)

; Amount of memory (in bytes) allocated for Stack
;为Stack分配的内存量(以字节为单位)
; Tailor this value to your application needs
;根据您的应用需求定制此值
; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Stack_Size      EQU     0x800      ;2K

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

  • EQU 是表示宏定义的伪指令,类似亍 C 诧言中的#define。伪指令的意思是指这个“指令”并丌会生
    成二进制程序代码,也丌会引起变量空间分配。 0x00000800 表示栈大小,注意这里是以字节为单位。

  • 开辟一段数据空间可读可写,段名 STACK,按照 8 字节对齐。 ARER 伪指令表示下面将开始定义一个
    代码段戒者数据段。此处是定义数据段。 ARER 后面的关键字表示这个段的属性。

    1. STACK :表示这个段的名字,可以任意意命名。
    2. NOINIT:表示此数据段不需要填入初始数据。
    3. READWRITE:表示此段可读可写。
    4. ALIGN=3 :表示首地址按照 2 的 3 次方对齐,也就是按照 8 字节对齐(SP mod 8 = 0)。
  • SPACE 这行指令告诉汇编器给 STACK 段分配 0x00000800 字节的连续内存空间

  • __initial_sp 紧接着 SPACE 诧句放置,表示了栈顶地址。 __initial_sp 只是一个标号,标号主要用亍表示
    一片内存空间的某个位置,等价亍 C 诧言中的“地址”概念。地址仅仅表示存储空间的一个位置,从 C 诧言
    的角度来看,变量的地址,数组的地址戒是函数的入口地址在本质上并无区别。

初始化栈指针(SP)

; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x400      ;1K

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit
  • 在栈的代码后面便是初始化堆的代码,其中堆的大小设为0x0000 0200(512B),栈名为HEAP,不初始化,可读可写,8(2^3)字节对齐。而__heap_base为堆的起始地址,__heap_limit为堆的结束地址,因为堆的由低地址向高地址生长。
PRESERVE8
THUMB
  • PRESERVE8 指定当前文件保持堆栈八字节对齐。
  • THUMB 表示后面的指令是 THUMB 指令集 ,CM4 采用的是 THUMB - 2指令集

向量表的设置

; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size
  • AREA 定义一块代码段,只读,段名字是 RESET。 READONLY 表示只读,缺省就表示代码段了。
  • 3 行 EXPORT 诧句将 3 个标号申明为可被外部引用, 主要提供给连接器用亍连接库文件戒其他其
    他文件。
__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         
   
   
   ;此处省略中间代码,详细参见文末链接中的文件
   
                DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
                DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
__Vectors_End

__Vectors_Size  EQU  __Vectors_End - __Vectors
   
  • 上面的这段代码是建立中断向量表,中断向量表定位在代码段的最前面。具体的物理地址由连接器的
    配置参数(IROM1 的地址)决定。如果程序在 Flash 运行,则中断向量表的起始地址是 0x08000000。
  • DCD 表示分配 1 个 4 字节的空间。每行 DCD 都会生成一个 4 字节的二进制代码。中断向量表存放
    的实际上是中断服务程序的入口地址。当异常(也即是中断事件)发生时,CPU 的中断系统会将相应的入
    口地址赋值给 PC 程序计数器,之后就开始执行中断服务程序。

配置系统时钟进入main

                AREA    |.text|, CODE, READONLY

; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
     IMPORT  __main
     IMPORT  SystemInit
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP
  • AREA 定义一块代码段,只读,段名字是 .text 。 READONLY 表示只读
  • 利用 PROC、 ENDP 这一对伪指令把程序段分为若干个过程,使程序的结构加清晰
  • WEAK 声明其他的同名标号优先亍该标号被引用,就是说如果外面声明了的话会调用外面的。 这个申明很重要,它让我们可
    以在 C 文件中仸意地方放置中断服务程序,只要保证 C 函数的名字和向量表中的名字一致即可。
  • IMPORT:伪指令用亍通知编译器要使用的标号在其他的源文件中定义。但要在当前源文件中引用,而且无论当前源文件是
    否引用该标号,该标号均会被加入到当前源文件的符号表中。
  • SystemInit 函数在文件 system_stm32f4xx.c 里面,这个文件在下期教程有详细讲解。
  • __main 标号表示 C/C++ 标准实时库函数里的一个初始化子程序 __main 的入口地址。该程序的一个主要作用是初始化堆栈
    (跳转__user_initial_stackheap 标号进行初始化堆栈的,下面会讲到这个标号),并初始化映像文件,最后跳转到 C 程序中的 main函
    数。这就解释了为何所有的 C 程序必须有一个 main 函数作为程序的起点。因为这是由 C/C++标准实时库所规,并且不能更改。
NMI_Handler     PROC
                EXPORT  NMI_Handler                [WEAK]
                B       .
                ENDP
HardFault_Handler\
                PROC
                EXPORT  HardFault_Handler          [WEAK]
                B       .
                ENDP
;此处省略中间代码,详细参见文末链接中的文件
USBWakeUp_IRQHandler

                B       .

                ENDP

                ALIGN
  • 此处为中断服务程序,如果有在C中定义了中断服务程序,就会使用C中的中断服务车程序。
  • B 是指死循环
;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
                 IF      :DEF:__MICROLIB           
                
                 EXPORT  __initial_sp
                 EXPORT  __heap_base
                 EXPORT  __heap_limit
                
                 ELSE
                
                 IMPORT  __use_two_region_memory
                 EXPORT  __user_initial_stackheap
                 
__user_initial_stackheap

                 LDR     R0, =  Heap_Mem
                 LDR     R1, =(Stack_Mem + Stack_Size)
                 LDR     R2, = (Heap_Mem +  Heap_Size)
                 LDR     R3, = Stack_Mem
                 BX      LR

                 ALIGN

                 ENDIF

                 END
  • 上面代码使用汇编诧言实现了 IF…….ELSE…………诧句。如果定义了 MICROLIB,那么程序是
    丌会 ELSE 分支的代码。
  • __user_initial_stackheap将由__main函数进行调用

参考:

安富莱教程

cnds文章

启动文件地址

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32启动文件分析(startup_stm32f10x_md.s) 的相关文章

随机推荐

  • shell脚本三个数据中的最大

    比较三个数 bin bash echo enter read a b c if a gt b then max a else max b fi if c gt max then max c fi echo max 转载于 https blo
  • 数据结构题目-线性表

    目录 问题 K 数据结构 绪论 求解多项式的值 问题 L 基础实验1 2 1 有序数组的插入 问题 M 数据结构作业01 一元多项式的求导 问题 N 数据结构作业01 一元多项式的求和 问题 O 算法2 1 集合union 问题 P 算法2
  • 对wireshark捕捉的数据包,对数据帧头部、IP数据包头部、ICMP头部进行分析

    利用wireshark抓包 数据如下 十六进制 1个字符占4比特 2个字符占1个字节 00 e0 fc 82 6c 01 00 e0 fc f7 7f 5e 08 00 45 00 00 54 00 1f 00 00 fe 01 85 86
  • 一键生成AppIcon 多种尺寸图标

    在我们开发APP的时候 客户总是不停地修改APPicon 感觉总是很麻烦 推荐大家使用一个一键生成的工具 http www makeicon cc 请测可以使用 瞬间感觉轻松了很多
  • Visual Studio Code——SSH连接Linux

    Visual Studio Code SSH连接Linux 记录使用连接linux服务器 一 连接远程服务器 安装插件工具 名称 Remote SSH 二 修改扩展文件 我这里直接把扩展文件修改好 等下直接就可以使用了 遇到的报错下面再总结
  • SQL-labs的第27关——union和select被屏蔽 报错注入(Get)

    注意 该关的空格 注释也被屏蔽了 1 判断闭合方式 输入语句 id 1 返回页面如下 我们发现返回的报错信息中在 号的后面跟着一个 号 这说明闭合方式是 2 爆破数据库名 用户名 版本 输入语句 id 1 26 26 updatexml 1
  • 【MySQL修改及删除操作】

    DML修改数据 前面呢给大家分享了添加数据的操作 今天就跟大家分享一下修改操作 小阿婆前面有说到DML是关于数据的操作 那么修改数据则用到了update关键字 我就不过多赘述啦 修改表中数据 update t student set sex
  • 主成分分析PCA,(主成分分析经常用于减少数据集的维数,同时保持数据集中的对方差贡献最大的特征)

    I 清空环境变量 PCA BP I 清空环境变量 clear all clc 导入数据 X xlsread inputd PCA主成分降维 Z MU SIGMA zscore X 计算相关系数矩阵 Sx cov Z 相关系数矩阵计算 计算相
  • 养老院人员定位手环真的如此智能?老人定位手环当然很智能-新导智能

    养老院人员定位手环为 新冠疫情 患者 护理院和养老院等老人和特别人员等在现有的基础上去掉心率 增加手臂体表温度检测 丈量1分钟 24小时能够自在调整 并经过低功耗NB IoT网络上签到后台 也能够外界蓝牙温度计 血糖仪或其他外设 上签到后台
  • 【Qt】qml TreeView的简单使用

    主要参考了官方demo Simple Tree Model Example 借鉴了https blog csdn net shado walker article details 56495059中roleNames 函数的写法 由于官方的
  • Flink简单教学2-本地安装和运行

    下载安装包 访问官网 下载最新版本 本教程使用Flink1 9版本 目录说明 bin flink 启动的脚本文件 lib flink 运行时jar包依赖 conf flink 启动的配置 如web端口 日志配置等 example flink
  • 小米笔记本装centos无法连接wifi问题

    1 打开终端 2 打开wifi nmcli r wifi on 3 搜索wifi nmcli dev wifi 4 连接wifi nmcli d wifi connect wifi名字 password 密码 网卡名 不知道wifi网卡名称
  • 浏览器原理+跨域+解决方案

    原网址 浏览器部分笔记 浏览器不同窗口cookie共享吗 JackieChan 的博客 CSDN博客 一 浏览器存储对象 1 cookie cookie是一种纯文本文件 大小只有4kb 每次发送非跨域html请求时都会自动携带 特性如下 c
  • java基础: Date类型最常用的时间计算(相当全面)

    目录 1 前言 2 具体方法实现 2 1 获取当天的开始时间 2 2 获取当天的结束时间 2 3 获取昨天的开始时间 2 4 获取昨天的结束时间 2 5 获取明天的开始时间 2 6 获取明天的结束时间 2 7 获取本周的开始时间 2 8 获
  • [echarts]clear和dispose的区别和使用场景

    clear和dispose是echarts提供的用于解决内存溢出的方法 内存溢出 当程序运行时需要的内存超出了当前应用系统的剩余内存时 就造成了内存溢出的情况 直观表现就是 卡死 所以只要使用echarts了 最好都clear或dispos
  • 工具使用(kali linux 中 nmap msf cs docker Goby)

    docker nmap MSF CS Goby docker 一 前言 其实我个人不常使用docker 到目前为止也只是搞了个xss靶场 在这里主要是先总结总结 以后用到也就方便了 主要分为两部分 一个是docker常用的一些连招操作 希望
  • DevExpress控件显示弹出注册对话框的应对方法

    删除Properties下的license licx 目前来看是可以的
  • 记一次从日立G400划一个LUN给dg数据库

    从日立G400划一个1T的lun 映像路径给DG主机 cat proc scsi scsi 为不重启主机识别设备 echo gt sys class scsi host host1 scan echo gt sys class scsi h
  • 等保合规2022系列

    2022等保合规指南 第一篇 四个核心问答 帮你读懂 等保 等级保护制度在我国已经推广了近20年了 如下图 从等保制度的逐渐成熟 到整个制度被上升到法律高度 无一不证明了网络安全是我国网络强国战略的重要组成部分 而网络安全等级保护是落实网络
  • STM32启动文件分析(startup_stm32f10x_md.s)

    初始化堆栈 初始化栈指针 SP 初始化栈指针 SP 向量表的设置 配置系统时钟进入main 一般而言 系统上电后第一个执行的是由汇编所编写的启动文件 其主要工作为一下五部分 初始化堆栈指针SP initial sp 初始化PC指针 令其 R