一个C程序5个段(pieces)组成

本文详细解释了C程序中的代码段、初始化数据段、未初始化数据段、栈段和堆段,并通过示例展示了它们在内存中的排列方式及作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个C程序一直以来都是由以下5个段(pieces)组成:


代码段(text segment):存放CPU执行的机器指令(machine instructions)。通常情况下,代码段是可共享的,使其可共享的目的是对于频繁被执行的程序,只需要在内存中有一份拷贝即可,比如文本编辑器(text editors),C编译器,shell等等。另外,代码段也通常是只读的,使其只读的原因是防止一个程序意外地修改了它的指令(prevent a program from accidentally modifying its instructions)。


初始化数据段/数据段(initialized data segment/data segment):该段包含了在程序中明确被初始化的变量。例如,一个不在任何函数内的C声明(C declaration)
int maxcount = 99;
使得变量maxcount根据其初始值被存储到初始化数据段。


未初始化数据段/bss段(uninitialized data segment/'bss' segment):

bss这个叫法是根据一个早期的汇编运算符而来,这个汇编运算符标志着一个块的开始(stood for 'block started by symbol')。在程序开始执行之前,bss段的数据被kernel初始化为0或者空指针(null pointers)。一个不在任何函数内的C声明
long sum[1000];
使得变量sum被存储到未初始化数据段/bss段中。

 

栈段(stack):函数的局部自动变量或者函数调用时候需要保存的信息,例如函数参数等都保存在栈段中. 每次当一个函数被调用,该函数的返回地址和一些关于caller的信息,比如某些寄存器的内容,将被首先存储到栈段。然后这个被调用的函数(caller)再为它的自动变量和临时变量(automatic and temporary variables)在栈段上分配空间。这就是C如何实现函数的递归调用。每次一个递归函数调用其本身,一个新的栈框架(stack frame)就会被使用,这样这个新实例栈里的一组变量就不会和该函数的另一个实例栈里面的变量互相干扰。

 

堆段(heap):用于动态内存分配(dynamic memory allocation)。一直以来,堆在内存中的位置是介于bss段和栈段之间。


图7.6(参见《UNIX高级环境编程》)显示了这5个段在内存中的典型排列。这是一张逻辑图,表示了一个程序在内存中看起来是怎么样的。对于一个给定的实现,没有强制的要求说必须按照这种方式来排列这5个段。

然而,这给了我们一种典型的便于描述的排列方式。运行在Intel x86处理器上的linux,代码段(text segment)从地址0x08048000开始(往上),栈底从地址0xC0000000往下(在这个特定的表示结构中,栈段从高地址向低地址扩展)。在堆顶和栈顶之间的虚拟地址空间是很大的(这保证了2个段不会互相干扰)。


在一个a.out中,还有许多段类型存在(Several more segment types exist in an a.out)。如符号表(symbol table),调试信息(debugging information),动态共享库的连接表(linkage tables for dynamic shared libraries)等。这些额外的section(不是segment)不会作为被一个进程执行的程序映象的一部分。


从图7.6中要注意到bss段的内容没有被存储到磁盘上的程序文件中(the program file on disk)。这是因为kernel在程序开始运行之前将该段都置为0。程序中唯一需要被存储到程序文件中的部分是代码段和初始化数据段。


命令size会报告这3个段的大小:代码段,初始化数据段,未初始化数据段。例如:
$ size /usr/bin/cc /bin/sh
text data bss dec hex filename
79606 1536 916 82058 1408a /usr/bin/cc
619234 21120 18260 658614 a0cb6 /bin/sh
第四和第五列是这3个段的总计大小,分别以十进制和十六进制表示出来。

### 回答1: "Operating Systems: Three Easy Pieces"(操作系统:三步轻松学)是一本由Remzi H. Arpaci-Dusseau和Andrea C. Arpaci-Dusseau编写的计算机科学教材。本书旨在介绍操作系统背后的核心原理和概念,以及其在计算机系统中的作用。 该书的内容涵盖了操作系统的多个方面,包括进程管理、内存管理、文件系统、输入输出、虚拟化、并发与并行等。它提供了广泛的范围,旨在帮助读者全面了解操作系统的基本概念和内部工作原理。 该书的第一部分介绍了操作系统的基本概念,例如进程、线程和调度算法。它解释了多任务处理的基本原理,并讨论了与并发性和并行性相关的问题。 第二部分讨论了内存管理和虚拟化技术,包括分页、分、内存分配和页面置换等。它还讨论了操作系统如何处理死锁和内存泄漏等问题。 第三部分则专注于文件系统和存储技术。它解释了文件系统的层次结构和存储管理,以及如何实现文件和目录的访问控制和保护机制。 总的来说,《操作系统:三步轻松学》这本书以易于理解和深入浅出的方式,介绍了操作系统的关键概念和原理。它旨在帮助读者建立对操作系统的基本了解,以及如何设计和实现一个高效稳定的操作系统。无论是计算机科学专业的学生、软件开发人员还是系统管理员,都可以从这本书中获得宝贵的知识和见解,以提升对操作系统的理解和应用能力。 ### 回答2: 《操作系统:三个简单的组成部分》是一本关于操作系统的英文书籍。该书由Remzi H. Arpaci-Dusseau和Andrea C. Arpaci-Dusseau合著。这本书旨在以简洁易懂的方式介绍操作系统的基本概念和原理。 书中主要涵盖操作系统的三个组成部分,即虚拟化、并发性和持久性。虚拟化是指操作系统利用物理资源来创建多个虚拟资源的能力,例如虚拟内存,使得多个程序可以在同一台机器上同时运行。并发性涉及操作系统如何管理和调度同时运行的多个任务。持久性是指操作系统如何管理和访问长期存储,例如硬盘或闪存。 书中通过详细的示例和清晰的解释,阐述了各种操作系统的基本概念和常见问题的解决方案。它还介绍了操作系统的设计原则和优化技术,以及一些常见的操作系统功能,如进程管理、内存管理和文件系统。 这本书是为初学者和其他对操作系统感兴趣的人编写的,而且不需要太多的预备知识。它的目标是帮助读者理解操作系统的基本原理和如何实现它们。 总之,《操作系统:三个简单的组成部分》是一本很好的操作系统入门书籍,它以易读易懂的方式介绍了操作系统的基本概念和原理。无论是对于学生、软件工程师还是对操作系统感兴趣的人来说,这本书都会提供有价值的知识和见解。 ### 回答3: 《操作系统:三部简单的作品》是一本关于操作系统的英文书籍。这本书由Remzi H. Arpaci-Dusseau和Andrea C. Arpaci-Dusseau撰写,旨在介绍操作系统的基本原理和概念。 该书主要分为三个部分,每个部分都涵盖一个关键主题。第一部分介绍了操作系统的概述和基本概念,包括进程、线程、调度、同步和死锁等。它通过一系列易懂的例子和实验帮助读者理解这些概念,并展示它们在实际操作系统中的应用。 第二部分深入讨论了操作系统的内存管理和虚拟内存的原理。它解释了内存分配、地址转换和页面置换等重要的内存管理技术,以及虚拟内存的概念和工作原理。读者可以通过实践性的编程练习来巩固所学知识。 最后一部分探讨了文件系统和存储技术。它介绍了文件系统的组织和功能,包括文件的访问权限、目录结构和磁盘调度算法。此外,它还讨论了存储技术的发展,例如RAID和闪存。 《操作系统:三部简单的作品》以其简洁明了的风格和通俗易懂的示例而闻名。它适用于那些对操作系统感兴趣的初学者和教育者。读者无需具备深厚的计算机科学背景,即可轻松理解书中的内容。 总之,这本书是一本介绍操作系统基本原理和概念的优秀教材。通过阅读《操作系统:三部简单的作品》,读者可以建立起对操作系统的深入理解,从而在实践中更好地应用和开发操作系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值