Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1740912
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: 系统运维

2012-03-29 12:53:21

历史上,一个C程序可以由以下部分组成:

1、代码段(text segment),CPU执行的机器指令。通过,代码段是可共享的,以便经常执行的程序只需在内存里单个拷贝,比如文本编辑器,C编译器,外壳,等等。还有代码段通常是只读的,为了阻止一个程序偶然修改了它的指令。


2、初始化的数据段(Initialized data segment),通常简称为数据段,包括在程序里特别初始化的变量。例如,C出现在任何函数外的声明int maxcount = 99;会导致这个变量以其初始值存储在初始数据段里。


3、未初始化的数据段(Uninitialized data segment),经常被称为“bss”段,在代表“block started by symbol”的古老的汇编操作之后命令。在这个段的数据被内核在程序开始执行前初始化为数字0或null指针。出现在任何函数外的C声明long sum[1000];导致这个变量被存储在未初始化的数据段里。


4、栈,存储自动变量和每次一个函数调用时保存信息的地方。每次一个函数被调用时,它要返回到的地址和关于调用者环境的特定信息,比如一些机器寄存器,被 保存在栈里。新调用的函数然后在栈上为自动和临时变量开辟空间。这是在C里的递归函数如何工作的。每次一个递归函数调用它自身时,一个新的栈框架被使用, 所以一堆变量不会和这个函数的其它实例的变量冲突。


5、堆,动态内存分配通常发生的地方。历史上,堆一直放在未初始化数据和栈之间。 


这些段的典型布局是:最低地址是代码段,其上是初始化数据,再上是未初始化数据,最高地址是命令行参数和环境变量,其下是栈,在栈和bss段之间是堆。这 是一个程序看起来的逻辑图,没有要求说一个给定的实现必须以这种风格排列它的内存。尽管如此,这给了我们一个可以描述的典型的排列。在Intel x86处理器上的Linux上,代码段从地址0x8048000开始中,而栈的底部从0xC0000000开始。(在这个特定的架构上,栈从高位地址向地 位地址增长。)在堆的顶部和栈的顶部之间的空间是巨大的。 


一些存在于一个a.out里的更多的段类型,包括符号表,调试信息,为动态共享库的链接表,等等。这些额外的段没有被载入作为被进程执行的程序映像的一部分。


注意未初始化数据段的内容没有存储在磁盘上的程序文件里。这是因为内核在程序开始运行时设置它为0。需要保存在程序文件部份只有代码段和初始化数据。


size命令报告代码、数据和bss段的(字节)尺寸。例如:


$ size /usr/bin/cc /bin/sh
   text       data        bss        dec        hex    filename
 296400       2000       5736     304136      4a408    /usr/bin/cc
  93358        900      10188     104446      197fe    /bin/sh


第三和第四列是前三个尺寸的总数。分别以十进制和十六进制表示。

阅读(635) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~