http://blog.jobbole.com/96225/#compiler_chs
图1 What The Operating System Does.bss: BSS全称为Block Started by Symbol(或者block storage segment)。在采用段式内存管理的架构中,BSS 段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS段属于静态内存分配。
.data: 表示数据段(data segment),通常用来存放程序中已初始化的全局变量的一块内存区,也属于静态内存分配
.text: 表示代码段(text segment),通常用来存放程序执行代码的一块内存区,这部分区域的大小在程序运行前就已经确定,并且内存区属于只读,代码段中也可能包含少量的只读常数变量,例如字符串常量等。
COM: 全称common段。在《程序员的自我修养》一书中,指出,如果全局变量初始化的值不为0,则保存在data段,值为0,则保存在bss段,如果没有初始化,则保存在common段。当变量为static,且未初始化时放在bss段,否则放在com段。
静态库:在UNIX系统中,一般使用 ar 命令生成静态库,并以 .a 作为文件扩展名,”lib”作为文件名前缀,链接时,使用”-l”选项,其后跟着库的名称,用于告诉链接器链接时所需要的库,这时无需加前缀和扩展名(例如,对于名为”libfred.a”的静态库,传递给链接器参数为”-lfred”)。在Windows平台上,静态库的扩展名为 .LIB。
共享库:共享库(shared libraries),其扩展名在 Unix 系统中为 .so,在 Windows 系统中为 .dll,在Mac OSX系统中为.dylib。对于这类库而言,通常,链接器没有必要将所有的符号都关联起来,而是贴上一个“我欠你(IOU)”这样的标签,直到程序真正运行时才对贴有这样标签的内容进行处理。当链接器发现某个符号的定义在共享库中,那么它不会把这个符号的定义加入到最终生成的可执行文件中,而是将该符号与其对应的库名称记录下来(保存在可执行文件中)。
静态库与共享库的区别:对于共享库,当程序开始运行时,操作系统会及时地将剩余的链接工作做完以保证程序的正常运行(在 main 函数开始之前,有一个小型的链接器——通常名为 ld.so,将负责检查贴过标签的内容,并完成链接的最后一个步骤:导入库里的代码,并将所有符号都关联在一起)。另外,共享库与静态库还存在一个巨大的差异,即链接的粒度(the granularity of thelink),如果程序中只引用了共享库里的某个符号(比如,只使用了 libc.so 库中的printf),那么整个共享库都将映射到程序地址空间中,这与静态库的行为完全不同,静态库中只会导入与该符号相关的那个目标文件。
The reason for this larger granularity is because modern operating systems are clever enough that you can save more than just the duplicate disk space that happens with static libraries; different running processes that use the same shared library can also share the code segment (but not the data/bss segments—two different processes could be in different places for their strtok after all). In order to do this, the whole library has to be mapped in one go, so that the internal references all line up to the same places—if one process pulled in a.o and c.o and another pulled in b.o and c.o, there wouldn't be any commonality for the OS to leverage.
网友评论