【C语言进阶剖析】40、程序的内存布局

1 什么是程序?

写完的 .c 文件是源文件。也叫源代码。
将源代码编译后,会生成可执行文件程序(Linux下是.out,windows下是.exe)。这个文件就是程序。也叫作可执行代码。

源代码与可执行文件的对应如下,也就是程序文件的布局:
在这里插入图片描述
可以看到,程序被编译器编译过后:

  • 初始化的全变量和静态局部变量在 .data 段,未初始化的全局变量和静态局部变量在 .bss 段,函数等代码在 .text 段。
  • 局部非静态变量存储在栈中,在右侧的图中没有对应,因为堆和栈是在程序运行开始后才正式存在,可执行程序中是没有栈、堆这样的存储区的。
  • File Header 是一个文件头,操作系统根据这个文件头就能判断这是一个什么样的可执行程序,那也就知道了怎么样来运行这个程序。

在上一篇博客中讲到全局变量和静态变量位于静态存储区,那也就是说 .data 段和 .bss 对应着静态存储区

前面一直说可执行程序,那么可执行程序在运行前和运行后有什么差异呢?,下面来看看程序与进程。

2 程序与进程

程序与进程不同

  • 程序是静态的概念,表现形式为一个可执行文件
  • 进程是动态的概念。程序由操作系统加载运行后得到的进程
  • 每个程序可以对应多个进程,每个进程只能对应一个程序

问题:包含脚本代码的文本文件是一种可行性程序吗?如果是,对应什么样的进程呢?

脚本文件是一个文本文件,我们经常会说运行某个脚本文件。其实脚本代码是一种可执行程序,但不是一种直接的可执行程序,既然是可执行程序一定对应进程,对应的是什么进程呢,下面来说:
在这里插入图片描述
一个可执行程序被操作系统加载运行后就得到了一个进程。对于 window 系统,双击一个 .exe 文件,操作系统加载这个文件,就得到一个进程。对于 Linux 通过命令行加载,和 window 原理一样。这个进程的功能是确定的。

对于脚本文件,操作系统首先查看脚本文件对应的脚本解释程序,然后加载脚本解释程序,就得到了进程,这个进程会反过来读取脚本文件,这个进程的功能是不确定的,取决于它读取并解释的执行的脚本文件。脚本文件不能直接被操作系统加载,需要加载脚本解释程序得到进程,这样一个脚本文件最终还是对应了一个进程。

3 程序的内存布局

可执行程序和加载后进程的布局如下:
在这里插入图片描述

File Header 是告诉操作系统如何运行这个程序,所以加载后进程中就没有 File Header 了。

各个段的作用:

  • 堆栈段在程序运行后才正是存在,是程序运行的基础
  • .bss 段存在的是未初始化的全局变量和静态变量,以及所有被初始化为 0 的全局或静态变量,在目标文件中,这个节不占据实际的空间,他仅仅是一个占位符,这是为了空间效率。
  • .data 段保存的是已经初始化的全局变量个静态变量
  • .text 段存放的是程序中的可执行代码
  • .rodata 段存放程序中的常量值,如字符串常量

4 程序术语的对应关系

  • 静态存储区通常指程序中的 .bss 和 .data 段
  • 只读存储区通常指程序中的 .rodata 段
  • 局部变量所占空间为栈上空间
  • 动态空间为堆中的空间
  • 程序可执行代码存放于 .text 段

问题:同时全局变量和静态变量,为什么初始化和未初始化的保存在不同段中?

  • C 规定,未初始化变量的初值为 0,这个清 0 的操作是由启动代码完成的,还有已初始化变量的初值的设置,也是由启动代码完成的。
  • 为了启动代码的简单化,编译链接器会把已初始化的变量放在同一个段:.data,这个段的映像(包含了各个变量的初值)保存在“只读数据段”,这样启动代码就可以简单地复制这个映像到 .data 段,所有的已初始化变量就都初始化了。
  • 而未初始化变量也放在同一个段:.bss,启动代码简单地调用 memset 就可以把所有未初始化变量都清0。

5 小结

1、程序源码在编译后对应可执行程序中的不同存储区
2、程序是静态概念,进程是动态概念
3、堆栈段是程序运行的基础,只存在于进程空间中
4、程序可执行代码存放于 .text 段,是只读的
5、.bss 和 .data 段用于保存全局变量个静态变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值