《程序员的自我修养》阅读笔记(一):
第一章 温故而知新
北桥(Northbridge):高速芯片,连接CPU、内存、高速图形设备。
南桥:汇总磁盘、usb、键盘、鼠标等再连接到北桥。
SMP(对称多处理器),多核处理器可以看作是SMP的简版。
可重入与线程安全:一个函数被重入,表明该函数没有执行完,而被重新调用。可重入是并发安全的强力保证。
第二部分 静态链接
第二章 编译和链接
第三章 目标文件里有什么
目标文件中通常包含:代码段(指令)、数据段(全局及静态变量)、BSS(未初始化变量等,事实上为空)。
objdump可用于查看目标文件;用objcopy可以将二进制文件生成为目标文件的一个段。
ELF文件头包含文件版本、程序入口地址、硬件平台等信息,文件头结构及相关常数通常定义在/usr/include/elf.h里。
ELF魔数,马屁股决定航天飞机。
段表。
重定位表.rel.text(一些给出绝对地址的,需要进行重定位)
字符串表(使用偏移量来表示/读取字符串)、
符号表(符号名,符号值,对变量和函数,符号值就是它们的地址);符号表结构很简单,是一个elf_32Sym结构(结构中包含,符号名、符号值、大小等元素)的数组,数组中每个元素对应一个符号。
函数签名、名称修饰。
强符号和弱符号、弱引用,可以用_attribute_((weak))和_attribute_((weakref))分别声明。弱符号和弱引用对库来说十分有用,允许用户定义的强符号覆盖库定义的弱符号,从而使程序可以使用自定义版本的库函数。
调试表。调试信息通常比程序代码和数据段大好几倍,因此最终最好去掉,Linux用strip命令可以去掉ELF文件中的调试信息。
第4章 静态链接
两步链接(Two-pass-Linking):
第一步,空间与地址分配。
第二步,符号解析与重定位。
COMMON块:多个弱符号出现在不同目标文件,它们类型不同,在COMMON块中按占最大空间的类型分配。如果对未初始时全局变量不以COMMON块方式处理,可在变量声明后加_attribute_((nocommon))。
C++相关问题
C++很多时候会产生重复代码,如模板、外部内联函数、虚函数表等都可能产生。解决模板产生重复代码的一个方法是将模板的实例代码放到一个单独的段,这样在链接的时候可以进行合并,对外部内联函数、虚函数表等也可以类似的方法处理。
函数级别链接。
ABI(Application Binary Interface)应用程序二进制接口,比API(Application Programming Interface,应用程序编程接口)更严格,要求参数、堆栈分布等细节问题一致。
静态库链接
一个简单的链接脚本:
第5章 Windows PE/COFF
Microsoft Visual C++的编译环境,编译器cl,链接器link,可执行文件查看器dumpbin等。