运动的诗章:运行时数据结构
编程语言理论的经典对立之一就是代码和数据的区别。有些语言(如Lisp)把二者视为一体。其他语言(如C语言)通常维持两者的区别。Internet蠕虫非常难以被人们所理解,因为它的攻击方式的原理就是把数据转换为代码。代码和数据的区别也可以认为是编译时和运行时的分界线。编译器的绝大部分工作与翻译代码有关;必要的数据存储管理的绝大部分在运行时进行。本章描述运行时系统中隐藏的数据结构。
学习运行时系统的3个理由:
*它有助于优化代码,获得最佳的效率;
*它有助于理解更高级的内容;
*当陷入麻烦时,它可以使分析问题更加容易。
a.out它是“assembler output”(汇编程序输出)的缩写形式!
UNIX中的可执行文件也是以一种特殊的方式加上标签,这样系统就能确认它们的特殊属性。为重要的数据定义标签,用独特的数字唯一地标识该数据是一种普遍采用的编程技巧。
超级块(superblock,UNIX文件系统中的基础数据结构)就是用下面这个神奇数字唯一标识的:
#define FS_MAGIC 0x011954
这个数字是Kirk McKusick的生日。Kirk是Berkeley fast文件系统的实现者,上面这个神奇数字仍然在source base中使用(位于文件sys/fs/ufs_fs.h)。
在a.out文件中也存在类似的神奇数字。在AT&T的UNIX System V发布之前,a.out文件被标识为神奇数字0407,偏移为零。0407是PDP-11一条无条件转移指令(相对于程序计数器)的二进制编码!如果在兼容模式下运行PDP-11或VAX,可以先执行文件的第一个字,然后这个神奇数字(位于那里)会带你跳过a.out文件,进入程序第一个真正的可执行指令。在SVr4中,可执行文件用文件的第一个字节来标注,文件以十六进制7F打头,紧跟在后面的第二至第四字节为“ELF”。