C语言-第31课 - 程序的内存布局

第31课 - 程序的内存布局

  1. 代码在可执行程序中有如下的对应关系

有初始值的放在data段,没有初始的放在bss段。静态存储区就对应了这两个区域。

我们写的函数,可移执行的代码段,放在text段。

这里并不见堆和栈的踪影,因为这只是我们的可执行文件的布局,并不会我们执行起来,进程的布局,所以是看不到堆和栈的。

  1. 文件布局在内存中的映射

高地址内存


File header



.text



.data


.bss


.data


.bss


.text


未映射区域


a.out


a.out进程的地址空间

当文件a.out运行的时候,在我们的内存空间中就出现了右侧的地址空间。由上到下分别是栈、堆(空闲列表法)、.bss、.data等等。我们的静态存储区是和我们的栈和堆是不同的,它不仅在程序运行的时候分配空间,而且会把空间中的内容最终写到我们的可执行文件中去。所以.bss(存的未初始化的数据)、.data(存的初始化的数据)、.text(我们编写的程序代码)。未映射区域存的内容(有自己独特的用处)不是我们这里介绍的,是在操作系统中该去介绍的。

  1. 各个段的作用

l 堆栈段是在程序运行后才正式存在,是程序运行的基础。C语言的执行是从main函数开始的,而这个函数的开始就是要有一些相应的活动记录,这是需要堆栈的。

l .bss段存放的是未初始化的全局变量和静态变量。没有初始值的文件,默认0。当映射这个区域的时候,直接将其中的内容都初始为0就好。

l .text段存放的是程序中的可执行代码。

l .data段保存的是那些已经初始化了的全局变量和静态变量。应将初始化了的值,当映射的时候,里面的值是要保存的。所以它和.bss段要分开保存。

l .rodata段存放的是程序中的常量值,如字符串常量。为了理解这个.rodata的含义,我们举一个例子:

#include<stdio.h>

int main()

{

char* p = "hello world\n";

printf(p);

}

运行结果:hello world

我们若做更改:

#include<stdio.h>

int main()

{

char* p = "hello world\n";

p[0] = ‘H‘;

printf(p);

}

运行出错,若是在linux系统下,就会显示段错误。

实际上我们的hello world就是存放在.rodata段,这个数据段的内容实际和.data段是并列的,但是这个段的数据是只读的。所以内容不能更改。

  1. 程序术语对应关系

l 静态存储区通常指程序中.bss和.data段

l 只读区通常指程序中的.rodata段

l 局部变量所占空间为栈上的空间

l 动态空间为堆上的空间

l 程序可执行代码存放在.text段

问:函数的地址对应程序的哪个段?

函数的地址就是程序的进程空里面存放代码段的某个地址。我们下面分析一下,我们知道函数的代码存放在.text段上,但是函数执行的数据又在活动记录(栈)上,这有没有问题呢?当然没问题,函数的那些代码最后是会被翻译成汇编代码的,汇编代码操作的是内存。就是只要有我们的栈顶指针esp,我们在操作的过程中,就会找到我们的所有的数据变量。即使存在字节对齐问题也是没有问题的。也就是我们能通过指针读出,活动记录里面的所有int、char等数据类型来给我们的函数使用。并且我们在在函数体内也可也去作.bss、.data等。

原文地址:https://www.cnblogs.com/free-1122/p/9794679.html

时间: 2024-11-10 14:58:27

C语言-第31课 - 程序的内存布局的相关文章

程序的内存布局——函数调用栈的那点事

[注]此文是<程序员的自我修养>的读书总结,其中掺杂着一些个人的理解,若有不对,欢迎拍砖. 程序的内存布局 现代的应用程序都运行在一个虚拟内存空间里,在32位的系统里,这个内存空间拥有4GB的寻址能力.现代的应用程序可以直接使用32位的地址进行寻址,整个内存是一个统一的地址空间,用户可以使用一个32位的指针访问任意内存位置. 在进程的不同地址区间上有着不同的地位,Windows在默认情况下会将高地址的2GB空间分配给内核,而Linux默认将高地址的1GB空间分配给内核,具体的内存布局如下图:

剖析程序的内存布局

原文标题:Anatomy of a Program in Memory 原文地址:http://duartes.org/gustavo/blog/ [注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下.一来自己复习,二来与大家分享.] 内存管理模块是操作系统的心脏:它对应用程序和系统管理非常重要.今后的几篇文章中,我将着眼于实际的内存问题,但也不避讳其中的技术内幕.由于不少概念是通用的,所以文中大部分例子取自32位x86平台的Linux和Windows系统.本系列第一篇文章讲述应用程序的内存

C语言程序的内存布局

一:C语言程序的存储区域 C语言编写的程序经过编绎-链接后,将形成一个统一的文件,它由几个部分组成,在程序运行时又会产生几个其他部分,各个部分代表了不同的存储区域: 1.代码段(Code or Text): 代码段由程序中的机器码组成.在C语言中,程序语句进行编译后,形成机器代码.在执行程序的过程中,CPU的程序计数器指向代码段的每一条代码,并由处理器依次运行. 2.只读数据段(RO data): 只读数据段是程序使用的一些不会被更改的数据,使用这些数方式类似查表式的操作,由于这些变量不需要更改

【面经】【转】C程序的内存布局

一个C语言程序一直以来都是由以下5个段组成: 1.代码段(text segmrnt):存放CPU执行的机器指令,通常情况下,代码段是可共享的,使其可共享的目的是对于频繁被执行的程序,只需要在没存中有有一份拷贝即可,比如文本编辑器,c编辑器,shell等等.另外,代码段也通常是只读的,使其只读的原因是防止一个程序意外地修改了它的指令. 2.初始化数据段/数据段(initialized data segment/data segmrnt): 该段包括了在程序中明确被初始化的变量. 3.未初始化数据段

Linux下C程序的内存布局

参考下列书籍中的对应章节: <Linux高级程序设计(第3版)>第3章Linux进程存储管理.相关视频:一.二. <C专家编程>第6章 运动的诗章:运行时数据结构. <UNIX环境高级编程(第2版)>第7章 进程环境  7.6 C程序的存储空间布局. 理解了上述知识就很容易明白,一个函数返回char *时的内存分配处理方案. char * func(...); 参考<C专家编程>P48

程序的内存布局

①代码在可执行程序中的对应关系 ②文件布局在内存中的映射 ③各个段的作用 1. 堆栈段在程序运行后才正式存在,是程序运行的基础 2. .bss段存放的是未初始化的全局变量和静态变量 3. .text段存放的是程序中的可执行代码 4. .data段保存的是那些已经初始化了的全局变量和静态变量 5. .ridata段存放程序中的常量值,如字符串常量 原文地址:https://www.cnblogs.com/wulei0630/p/8643320.html

一起talk C栗子吧(第一百三十一回:C语言实例--C程序内存布局三)

各位看官们,大家好.上一回中咱们说的是C程序内存布局的样例,这一回咱们继续说该样例.闲话休提,言归正转.让我们一起talk C栗子吧. 看官们,关于C程序内存布局的样例,我们在前面的两个章回都介绍过了,这一回我们将对前面章回中的内容进行总结和提示. 内存布局总结 C程序的内存布局主要有四个分区:代码区,数据区(data和bss).堆区和栈区.能够使用readelf -S filename查看各个分区的内存地址.这四个分区在内存中从低地址空间開始依次向高地址延伸.我们再次使用前面章回中的图直观地展

【转载】图说C++对象模型:对象内存布局详解

原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在VS2013上得到验证.不同的编译器在内存布局的细节上可能有所不同.文章如果有解释不清.解释不通或疏漏的地方,恳请指出. 回到顶部 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个概念可以解释C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各种支持的底层

c++ 对象内存布局详解

今天看了的,感觉需要了解对象内存的问题. 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个概念可以解释C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各种支持的底层实现机制. 直接支持面向对象程序设计,包括了构造函数.析构函数.多态.虚函数等等,这些内容在很多书籍上都有讨论,也是C++最被人熟知的地方(特性).而对象模型的底层实现机制却是很少有书籍讨论的.对象模型的底层实现机制并未标准化,不同的编译器有一定的自由来设计对象模型的实现细节.在我看来,对