程序结构理解(1) 以stm32为例

内容参考地址:

https://blog.csdn.net/xujidong1576324301/article/details/72851023

https://blog.csdn.net/zhy557/article/details/80832268

 

程序中的几个段理解

有些技术文章中会直接使用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. 
.sbss    @ 
注意:源程序中.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

即可

其他都都存在这个字段内

同理

程序结构理解(1) 以stm32为例_第1张图片

这个Reset_Handler函数内容也存放在SECTION .text:CODE:REORDER(2)中

其他同理

 

你可能感兴趣的:(stm32,程序运行流程分析)