程序中的几个段理解
有些技术文章中会直接使用RO,请注意区分RO和RO-data的区别。
Code:即代码域,它指的是编译器生成的机器指令。
RO_data:ReadOnly data,即只读数据域,它指程序中用到的只读数据,全局变量,例如C语言中const关键字定义的全局变量就是典型的RO-data。
RW_data:ReadWrite data,即可读写数据域,它指初始化为“非0值”的可读写数据,程序刚运行时,这些数据具有非0的初始值,且运行的时候它们会常驻在RAM区,因而应用程序可以修改其内容。例如全局变量或者静态变量,且定义时赋予“非0值”给该变量进行初始化。
ZI_data:ZeroInitialie data,即0初始化数据,它指初始化为“0值”的可读写数据域,它与RW_data的区别是程序刚运行时这些数据初始值全都为0,而后续运行过程与RW-data的性质一样,它们也常驻在RAM区,因而应用程序可以更改其内容。包括未初始化的全局变量,和初始化为0的全局变量。
RO:只读区域,包括RO_data和code。
当程序存储在ROM中时,所占用的大小为Code + RO_data + RW_data 。
当程序执行时, RW_data和 ZI_data在RAM中,RO_data和code视cpu架构(51、arm、x86)不同处于ROM或者RAM中。其中ZI_data对应了BSS段,RW_data对应数据段,code对应代码段, RO_data对应数据段。
汇编系统预定义的段名
.text @代码段
.data @初始化数据段 .data Read-write initialized long data.
.bss @未初始化数据段
.sdata @ .sdata Read-write initialized short data.
.***ss @
注意:源程序中.bss段应该在.text段之前。
程序进程中的分区
相关概念:堆(heap),栈(stack),BSS段,数据段(data),代码段(code /text),全局静态区,文字常量区,程序代码区。
BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。
数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。
代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。
栈(stack):栈又称堆栈,用户存放程序临时创建的局部变量。在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的后进先出特点,所以栈特别方便用来保存/恢复调用现场。
全局静态区,文字常量区,程序代码区是从内存地址分配的角度来描述的。
全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
文字常量区—常量字符串就是放在这里的。
程序代码区—存放函数体的二进制代码。
以上几个概念的对应关系如下表中所示:
备注:粉色部分的code和RO_data文字颜色为灰色,表示可能发生在ROM,也可能发生在RAM,根据架构不同而不同。
startup_stm32f10x_hd.s 启动文件中的几个代码
这一段重点介绍了这段启动代码干了些什么
1、初始化SP(堆栈指针)
2、将PC(程序指针)设置为_iar_program_start
3、设置中断向量表的地址
4、配置系统时钟,并且将挂载外部SRAM作为数据存储器
5、跳转到main函数执行C库
MODULE ?cstartup ;表示MODULE ?cstartup ;标志汇编模块的开始 这里不用升入理解这个
;没有多大的意思 看做一个标签 理解成程序执行入口 即可
;; Forward declaration of sections.
;;段前置声明(类似于c语言中定义一个函数在使用前需要声明一下)
;;格式:SECTION section :type [flag] [(align)]
;;NOROOT表示如果这个段里的标号(如CSTACK/ .intvec)没有引用,则被舍弃;ROOT表示不舍弃
;;(1)表示字节对其,(2)表示4字节对其,(3)表示8字节对其
SECTION CSTACK:DATA:NOROOT(3) ;;定义CSTACK数据段
SECTION .intvec:CODE:NOROOT(2) ;;定义.intvec代码段
EXTERN __iar_program_start ;;声明外部函数,此函数是iar的官方库函数,无法看到函数原型
EXTERN SystemInit ;;声明外部函数,主要功能是设置初始化系统时钟,配置SRAM
PUBLIC __vector_table ;;类似于全局变量,外部可以调用
DATA
我们不用深入的列举这个命令 我们主要了解 定义一个名字叫“CSTACK”数据段和一个名字叫“.intvec”代码段 至于用不用我们不用管
同时我们了解到定义了 两个外部函数__iar_program_start和 SystemInit
还定义了一个全局变量 __vector_table
从就近原则来看 则.intvec代码段内容为
从 EXTERN __iar_program_start开始 经过__vector_table 到 PUBWEAK Reset_Handler 结束
其中除去全局声明即可
这里要除去
EXTERN __iar_program_start
EXTERN SystemInit
PUBLIC __vector_table
DATA
和
THUMB
即可
其他都都存在这个字段内
同理
这个Reset_Handler函数内容也存放在SECTION .text:CODE:REORDER(2)中
其他同理
程序中的几个段理解
有些技术文章中会直接使用RO,请注意区分RO和RO-data的区别。
Code:即代码域,它指的是编译器生成的机器指令。
RO_data:ReadOnly data,即只读数据域,它指程序中用到的只读数据,全局变量,例如C语言中const关键字定义的全局变量就是典型的RO-data。
RW_data:ReadWrite data,即可读写数据域,它指初始化为“非0值”的可读写数据,程序刚运行时,这些数据具有非0的初始值,且运行的时候它们会常驻在RAM区,因而应用程序可以修改其内容。例如全局变量或者静态变量,且定义时赋予“非0值”给该变量进行初始化。
ZI_data:ZeroInitialie data,即0初始化数据,它指初始化为“0值”的可读写数据域,它与RW_data的区别是程序刚运行时这些数据初始值全都为0,而后续运行过程与RW-data的性质一样,它们也常驻在RAM区,因而应用程序可以更改其内容。包括未初始化的全局变量,和初始化为0的全局变量。
RO:只读区域,包括RO_data和code。
当程序存储在ROM中时,所占用的大小为Code + RO_data + RW_data 。
当程序执行时, RW_data和 ZI_data在RAM中,RO_data和code视cpu架构(51、arm、x86)不同处于ROM或者RAM中。其中ZI_data对应了BSS段,RW_data对应数据段,code对应代码段, RO_data对应数据段。
汇编系统预定义的段名
.text @代码段
.data @初始化数据段 .data Read-write initialized long data.
.bss @未初始化数据段
.sdata @ .sdata Read-write initialized short data.
.***ss @
注意:源程序中.bss段应该在.text段之前。
程序进程中的分区
相关概念:堆(heap),栈(stack),BSS段,数据段(data),代码段(code /text),全局静态区,文字常量区,程序代码区。
BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。
数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。
代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。
栈(stack):栈又称堆栈,用户存放程序临时创建的局部变量。在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的后进先出特点,所以栈特别方便用来保存/恢复调用现场。
全局静态区,文字常量区,程序代码区是从内存地址分配的角度来描述的。
全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
文字常量区—常量字符串就是放在这里的。
程序代码区—存放函数体的二进制代码。
以上几个概念的对应关系如下表中所示:
备注:粉色部分的code和RO_data文字颜色为灰色,表示可能发生在ROM,也可能发生在RAM,根据架构不同而不同。
startup_stm32f10x_hd.s 启动文件中的几个代码
这一段重点介绍了这段启动代码干了些什么
1、初始化SP(堆栈指针)
2、将PC(程序指针)设置为_iar_program_start
3、设置中断向量表的地址
4、配置系统时钟,并且将挂载外部SRAM作为数据存储器
5、跳转到main函数执行C库
MODULE ?cstartup ;表示MODULE ?cstartup ;标志汇编模块的开始 这里不用升入理解这个
;没有多大的意思 看做一个标签 理解成程序执行入口 即可
;; Forward declaration of sections.
;;段前置声明(类似于c语言中定义一个函数在使用前需要声明一下)
;;格式:SECTION section :type [flag] [(align)]
;;NOROOT表示如果这个段里的标号(如CSTACK/ .intvec)没有引用,则被舍弃;ROOT表示不舍弃
;;(1)表示字节对其,(2)表示4字节对其,(3)表示8字节对其
SECTION CSTACK:DATA:NOROOT(3) ;;定义CSTACK数据段
SECTION .intvec:CODE:NOROOT(2) ;;定义.intvec代码段
EXTERN __iar_program_start ;;声明外部函数,此函数是iar的官方库函数,无法看到函数原型
EXTERN SystemInit ;;声明外部函数,主要功能是设置初始化系统时钟,配置SRAM
PUBLIC __vector_table ;;类似于全局变量,外部可以调用
DATA
我们不用深入的列举这个命令 我们主要了解 定义一个名字叫“CSTACK”数据段和一个名字叫“.intvec”代码段 至于用不用我们不用管
同时我们了解到定义了 两个外部函数__iar_program_start和 SystemInit
还定义了一个全局变量 __vector_table
从就近原则来看 则.intvec代码段内容为
从 EXTERN __iar_program_start开始 经过__vector_table 到 PUBWEAK Reset_Handler 结束
其中除去全局声明即可
这里要除去
EXTERN __iar_program_start
EXTERN SystemInit
PUBLIC __vector_table
DATA
和
THUMB
即可
其他都都存在这个字段内
同理
这个Reset_Handler函数内容也存放在SECTION .text:CODE:REORDER(2)中
其他同理
举报