程序映像的布局

---摘自UNIX系统编程第二章

1程序与进程的转换

       C编译器将每个源文件翻译成一个目标文件,然后编译器将这些单个的目标文件同必需的一些库相链接,形成一个可执行模块。程序运行或执行时,操作系统将可执行模块拷贝到主存储器的程序映像(program image)中去。

       当操作系统向内核添加了适当的信息,并为运行程序代码分配了必要的资源之后,程序就变成了进程。进程拥有地址空间(它可以访问的内存)和至少一个被称为线程的控制流。进程的变量可以在进程的生命周期中始终存在(静态存储),也可以在执行进入一个程序块时自动分配,离开这个程序块时将其释放(自动存储)。

 

2 程序映像的布局

       加载之后,可执行程序看起来占据了一个连续的内存块,这个连续的内存块被称为程序映像。图1显示的是程序映像在它的逻辑地址空间中的一个而已实例。程序映像有几个不同的分区。程序文本或代码显示在内存低端地址中。在映像中已初始化和未初始化的静态变量也有自己的分区。其他的分区包括堆、栈和环境。

                             1

活动记录:

       是在进程栈顶端分配的一个内存块,用来装载调用过程中函数的执行上下文。每次函数调用都在栈上创建一个新的活动记录。假如嵌套的函数调用按照后调用先返回的次序工作,那么函数返回时会将活动记录从栈中删除。

       活动记录包括返回地址、参数(参数值从相应的命令行参数中拷贝而来)、状态信息和调用时某些CPU寄存器值的拷贝。进程人记录表示的调用中返回时,要恢复寄存器的值。活动记录中还包括函数执行时在其内部分配的自动变量。活动记录的特定格式取决于硬件和编程语言。

       在声明时没有显示初始化的静态变量占据不同的分区。通常,已初始化的静态变量是磁盘上可执行模块的一部分,而未初始化的表态变量则不是。当然,自动变量不是可执行模块的一部分,因为只有当定义它们的程序块被调用时,它们才被分配。除非程序显示地对自动变量进行初始化,否则,它们的初始值是不确定的。

       尽管程序映像看起来占据了一个连续的内存块,但实际上,操作系统将程序映像映射到不一定连续的物理内存块中。通常的映射将程序映像划分成相同大小的片,这些片被称为页。操作系统将这些页加载到内存中,当处理器引用某页上的内存时,操作系统会从一个表中查找这一页的物理位置。

 

在程序映像中,已初始化的静态变量和未初始化的静态变量占据不同的分区。通常,已初始化的静态变量是磁盘上可执行模块的一部分,而未初始化的静态变量则不是。

例:用ls -l对下面两个C程序的可执行模块的大小进行比较,会得到不同的结果。

版本1

int arry[50000] = {1, 2, 3, 4};

int main()

{

       arry[0] = 3;

       return 0;

}

 

版本2

int arry[50000];

int main()

{

       arry[0] = 3;

       return 0;

}

 

版本1的可执行模块比版本2的长大约200000字节,因为1中的array是已初始化的静态数据,是可执行模块的一部分。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值