P117
UNIX中段和Intel x86架构中的段:
- 在UNIX中,段表示一个二进制文件相关的内容块。
- 在Intel x86的内存模型中,段表示一种设计的结果。在这种设计中,地址空间并非一个整体,而是分成一些64K大小的区域,称之为段。
本章所有关于段的术语都是指UNIX上的段。
P118
- 数据段保存在目标文件中。
- BSS(Block Started by Symbol)段不保存在目标文件中(除了记录BSS段在运行时所需要的大小),但BSS段并不占据目标文件的任何空间。
- 文本段是最容易受优化措施影响的段。
- a.out文件的大小受调试状态下编译的影响,但段不受影响。
P120
为什么a.out要以段的形式组织?段可以方便地映射到链接器在运行时可以直接载入的对象中。
- 数据段包含经过初始化的全局和静态变量以及它们的值。
- BSS段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段之后
- 数据段和BSS段统称为数据区。
- 堆栈段用于保存局部变量、临时数据、传递到函数中的参数。
- 我们还需要堆(heap)空间,用于动态分配的内存。
当我们用到共享库是,内存分配如下图。
P122
堆栈段的作用:
- 堆栈为函数内部声明的局部变量提供存储空间。这节变量被称为“自动变量”。
- 进行函数调用时,堆栈存储与此有关的一些维护性信息,即过程活动记录。
- 堆栈也可以被用作展示存储区。 有时候程序需要一些临时存储,比如计算一个很长的算术表达式时,它可以把部分计算结果压到堆栈中。
alloc()函数分配的内存就位于堆栈中。如果想要内存在函数调用后仍然有效,就不要用alloc()来分配内存。- 除了函数的递归调用外,堆栈并非必需。 因为编译时可以知道局部变量、参数和返回地址所需空间的额固定大小,并可以将他们分配于BSS段。
P128
setjmp和longjmp:
setjmp(jmp_buf j)必须首先被调用。 它表示“使用变量j记录现在的位置。函数返回零”longjmp(jmp_buf j, int i)可以接着被调用。 它表示“回到j所记录的位置,让他看上去像是从原先的setjmp()函数返回一样。但是函数返回i,使代码能够知道它实际上是通过longjmp()返回的。”- 当使用于
longjmp()时,j的内容被销毁。 goto语句不能跳出C语言当前的函数。