没初始化的全局变量伪指令会按照一定方法顺序在一区域划分好变量对应的RAM地址.
已初始化和未初始化的局部变量和全局变量在内存中如何分布?
阿基米东 2020-12-31 01:00:22 415 收藏
分类专栏: 嵌入式面试精选 文章标签: C语言 面试题 内存分布 堆栈
版权
玩转STM32MP1
从 STM32MP1 开始玩转 Linux
阿基米东
¥9.90
订阅专栏
在 C 语言中,通常可以把内存理解为四个分区:栈、堆、全局/静态存储区和常量存储区。
栈(stack,也称“堆栈”)
通常是用于存储在编译期间就能确定存储大小的变量,用于在函数作用域内创建,在离开作用域后自动销毁的变量的存储区。通常是局部变量、函数参数等的存储区。它的存储空间是连续的,两个紧密挨着定义的局部变量,它们的存储空间也是紧挨着的。栈的大小是有限的,在 Linux 中可以通过命令 ulimit -s 查看默认栈空间大小,默认情况下为 8192 KB(即 8MB)。因此如果在程序内部分配超大的数据,有可能会出错。当然,栈空间大小是可以调整的。
堆(heap)
通常是存储那些在编译期间不能确定存储大小的变量,它的存储空间是不连续的,一般由 malloc(或 new)函数来分配内存块,并且需要用 free(delete)函数释放内存。如果程序员没有释放掉,那么就会出现常说的内存泄漏问题。需要注意的是,两个紧挨着定义的指针变量,所指向的 malloc 出来的两块内存并不一定的是紧挨着的,所以会产生内存碎片。另外需要注意的一点是,堆的大小几乎不受限制,理论上每个程序最大可达 4GB。
全局/静态存储区
和“栈”一样,通常是用于存储那些在编译期间就能确定存储大小的变量,但它用于的是在整个程序运行期间都可见的全局变量和静态变量(使用 static 修饰)。
常量存储区
和“全局/静态存储区”一样,通常是用于存储那些在编译期间就能确定存储大小的常量,并且在程序运行期间,存储区内的常量是全局可见的。这是一块比较特殊的存储去,它们里面存放的是常量,不允许被修改。
因此,局部变量存放在 栈区(stack),如果使用 static 修饰,则存放在全局/静态区,跟是否初始化无关。全局变量存放在 全局/静态区,静态存储区又包括 BSS 段和数据段,未初始化的全局变量存放在 BSS 段,已初始化的全局变量则存放在 数据段。
扩展阅读:
BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS 是英文 Block Started by Symbol 的简称。BSS 段属于静态内存分配,其内容由操作系统初始化(清零,裸机程序需要手动清零),BSS 段不占用可执行文件的空间。
数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配,其内容由程序初始化,需要占用可执行文件的空间。
代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
————————————————
版权声明:本文为CSDN博主「阿基米东」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lu_embedded/article/details/112001324
C规定,未初始化变量的初值为0,这个清0的操作是由启动代码完成的,还有已初始化变量的初值的设置,也是由启动代码完成的。
为了启动代码的简单化,编译链接器会把已初始化的变量放在同一个段:.data,这个段的映像(包含了各个变量的初值)保存在“只读数据段”,这样启动代码就可以简单地复制这个映像到 .data 段,所有的已初始化变量就都初始化了。
而未初始化变量也放在同一个段:.bss,启动代码简单地调用 memset 就可以把所有未初始化变量都清0。
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
https://zhidao.baidu.com/question/752408126770120804.html
没初始化的全局变量伪指令会按照一定方法顺序在一区域划分好变量对应的RAM地址.
伪指令类似ORG指定存储器位置,段地址,微机原理中伪指令定义变量都不占用ROM空间
指令是在执行阶段发挥作用的,由CPU(Intel、AMD等)来执行。
伪指令是在编译阶段发挥作用的,由汇编器(MASM、TASM等)来解释。不占用ROM空间