此文的主要目是为了更加深入的理解STM32系列单片机StartUp.S汇编文件,因为里面很多符号牵扯到ld连接文件。像最新的stm32F7,stm32H7这类极有可能使用外部存储器(ROM/RAM)。在建立工程时,需要建立在SDRAM中执行代码的线仿真环境和将程序地址连接至外部存储器的开发环境,或者将特定代码和数据放入TCM区的开发环境;这些工作都需要去修改芯片的ld连接文件。要想修改连接文件,则需要掌握底层汇编文件和ld连接文件语法。
StartUp.s其中使用到的关键字(伪指令):
参考文件:
Assembler.pdf 下载地址:https://www.eecs.umich.edu/courses/eecs373/readings/Assembler.pdf
Linker.pdf 下载地址:https://www.eecs.umich.edu/courses/eecs373/readings/Linker.pdf
.syntax name
语法选择
ARM和THUMB指令支持两种略有不同的语法。
默认值divided(分裂的) 旧样式,下面的指令使用ARM和THUMB各自独立的语法。
unified (统一的)新样式,下面的指令使用ARM和THUMB通用格式。
.cpu name
选择目标处理器。 与gcc “ -mcpu”命令行选项作用相同。例如cortex-m7
.fpu name
选择要使用的浮点单元类型。 与gcc “ -mfpu”命令行选项作用相同。
softvfp 软浮点
fpv5-d16 or fpv5-sp-d16 cortex-M7 单精度硬件浮点
fpv4-d16 or fpv4-sp-d16 cortex-M4 单精度硬件浮点
fpv5-dp-d16 cortex-M7 双精度硬件浮点
机器相关指令
.thumb
使用thumb模式等价于.code 16;gcc -mthumb
.arm
使用ARM模式等价于.code 32;gcc -marm
.global symbol [,...,symbol_n]
建立一个全局符号(symbol),.global使该符号对ld(连接文件)可见。
.word expression
在当前位置放一个word型的值,这个值就是expression;可以理解为一个变量或者数据定义,这个变量同样对对ld(连接文件)可见。
.section section_name [, “flags”[, %type[,flag_specific_arguments]]]
定义一个段,每一个段以段名为开始,以下一个段名或者文件结尾为结束。
段标志"flags": a:可分配 ; w:可写段;x:执行段;M:可合并;S:包含零个终止的字符串;G:段组成员;T:用于线程本地存储;
type:
%progbits
段内包含数据。
%nobits
段中不包含数据(即该段只占用空间)。
%note
段内包含程序以外使用的数据。
%init_array
段包含一个指向init函数的指针数组。(初始化)
%fini_array
段包含一个指向finish函数的指针数组。(完成)
%preinit_array
段包含一个指向pre-init函数的指针数组。(与初始化)
预定义段 .text、.data、.bss(.sction .text.section_name...)
.text、.data和.bss将汇编系统预定义的段名编译到相应的代码段、数据段和bss段。
bss段通常是指用来存放程序中未初始化的全局变量的一块内存区域;
data数据段通常是指用来存放程序中已初始化的全局变量的一块内存区域;
symbol:(符号)
当前位置的一个别称, .也表示当前位置。
.weak names
该伪指令在符号名称的逗号分隔列表上设置弱属性。 如果符号不存在,将创建它们。(弱定义,如果有其他强定义则用强定义替代)
.type name , %
(ELF格式下隐含的标识一个段的开始)此伪指令用于设置符号的类型。
类型描述包括:
%function: Mark the symbol as being a function name.符号是函数名
%object: Mark the symbol as being a data object.符号为数据对象
%tls_object:Mark the symbol as being a thead-local data object.将符号标记为线程本地数据对象。
%common: Mark the symbol as being a common data object.将符号标记为公共数据对象。
.size name , expression
(ELF格式下隐含标识一个段的结束)该指令设置与符号名称关联的大小。字节大小由可使用标签算术的表达式计算得出。 该伪指令通常用于设置功能符号的大小。
.thumb_set
等效于.set指令,因为它创建了一个符号,该符号是另一个符号的别名(可能尚未定义)。
该指令还具有添加的属性,因为它以.thumb_func指令相同的方式将别名符号标记为thumb函数入口点。
.equ(.set)
该指令设置符号的值。
.zero
.space/.skip
分配number_of_bytes字节的数据空间,.zero伪操作用0填充内存,.space/.skip用值为fill_byte填充内存,若未指定该值,缺省填充0。