$1
段的概念
目标文件和可执行文件有很多的格式,比如ELF 等,但这些格式有一个共同的概念,那就是“段”(segments),就目标文件而言,段就是是二进制文件中简单的区域,一个段就包括好几个sections.
段是二进制文件相关的内容块,c语言中的各个部分会出现在段中的哪个部分下面的图显示的很明确;
初始化的全局变量放在数据段上,未初始化的全局变量放在bss段中。
bss段是个特殊的段,他存放的的是没有值的变量,因此并不需要保存这些变量的映像,运行时所需要的bss的大小保存在目标文件中,但bss段不占用目标文件的任何空间。
$3
操作系统在a.out里干了什么
段在运行的时候就是内存中的一段区域,载入器把文件中的一段载入到内存中,程序的文本段包含程序的指令,值部分是一般是只读的,下面图显示了可执行文件在内存的布局:
虚拟地址的最低部分未被映射,也就是说它位于进程的地址空间但未被映射成物理地址,所以任何对他的应用都是非法的,一般的他是从0开始的几kb的字节,用于捕捉空指针和小整形的指针的内存引用情况。
下面图是有共享库的内存的使用情况;
堆栈段的作用:
1堆栈为函数内部的局部变量提供了存储空间。这些变量称为自动变量
2.进行函数调用时,堆栈存储了一些用到的维护的信息,包括调用者的地址,一些寄存器的值,和任何不适合装入寄存器的参数
3.堆栈也可以用于暂时存储区。比如在函数递归调用时,存储一个变量的多个实例。
alloca()函数分配的内存就在堆栈中
在大多数的处理器中,堆栈是向下增长的,也就是向着低地址的方向增长。
$4
函数调用时发生了什么?
c语言提供了一个自动服务是跟踪调用链,哪些函数调用了哪些函数,当下一个return之行后,将返回到什么地方,解决这给经典的问题的途径就是堆栈的活动纪录,过程活动纪录是一个数据结构,用于支持函数的调用,并纪录调用结束后返回调用点所需要的所有的信息。
$
5
auto 和 static
auto 是自动分配内存变量,如果是在函数的内部,当函数返回时,该变量可能会被覆盖,如果想返回一个函数内部的变量指针,可以在变量声明的时候加上static。
这种自动分配和编译时的静态分配和堆上分配不一样。
$6
unix中的堆栈段
在unix中,当进程需要更大的地址空间的时候,堆栈会自动的增长。