内容参考地址:
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
即可
其他都都存在这个字段内
同理
这个Reset_Handler函数内容也存放在SECTION .text:CODE:REORDER(2)中
其他同理