上一章提到了源代码,源代码在任何情况下都能够编译和显示,但它并不能直接运行,因为CPU只能够解释和执行的代码叫做本机代码,所以使用源代码时都会转换成本机代码被CPU理解后运行。
我们对EXE程序进行转储后,可以得知本机代码的本质就是数值序列其中的每个值都代表某个指令和数据。其中转储是将文件内容按1字节2位十六进制的形式显示出来。
负责将高级语言编写的源代码翻译成本机代码的程序叫做编译器,编译器会读取源代码的内容将其翻译成本机代码,可以理解为编译器中有一张源代码和本机代码的对应表。CPU的类型不同对应的本机代码也不同所以不同类型的CPU使用的编译器也不同。编译器的本质也是一种程序,所以也有对应的运行环境,当编译器本身运行在一种CPU上却可以编写另一种CPU的代码,这种编译器被称为交叉编译器。
但编译后并不是可以直接运行的EXE文件而是包含本机代码的目标文件,因为缺少了一些包含函数的目标文件,只需将所有必要的目标文件链接起来就可以生成EXE文件,将多个目标文件的拼接在一起生成一个EXE文件的过程称为链接,用于完成这一操作的程序称为链接器。
有些通用代码需要连接在所有代码的开头,这些代码被称为启动代码
还有一些文件叫做库文件,库文件有多个目标文件打包而成而不包含在源代码中的函数反而包含在库文件之中的函数叫做标准函数。使用库文件有两个好处,一个是指定时方便,另一个则是可以隐藏标准函数的源代码。windowsAPI也是一些函数,但这种函数并不是以库的形式存放的,而是以静态链接库与动态链接库存在的。
以上是如何生成EXE文件,在EXE五年间中变量和函数被分配的内存地址是虚拟的,在运行时将会转为实际,链接器会在文件开头记录需要进行转换的各个位置,这些信息被称为重定位信息。