读《程序是怎样跑起来的》第八章有感
在第八章中了解了将源代码转换到本地代码的流程。
CPU可以解析和运行的程序形式称为本地代码。通过编译源代码得到本地代码。源代码完成后,就可以编译生成可执行文件了。负责实现该功能的是编译器。计算机只能运行本地代码。用某种编程语言编写的程序就成为源代码,保存源代码的文件成为源文件。用C语言编写的源文件的扩展名通常是“.c”。CPU能直接解析并运行的不是源代码而是本地代码的程序。作为计算机电脑的Pentium等CPU,也只能解释已经转换成本地代码的程序内容。本地这个术语有“母语的”意思。对CPU来说,母语就是机器语言,而转换成机器语言的程序就是本地代码。用任何编程语言编写的源代码,最后都要翻译成本地代码,否则CPU就不能理解。也就是说,即使使用不同编程语言编写的代码,转换成本低代码后,也都变成用同一种语言来表示了。
Windows中EXE文件的程序内容,使用的就是本地代码,本地代码的内容是人类无法理解的,正因如此,才有了用人类容易理解的C语言等编程语言来编译源代码。
能够把C语言等高级编程语言编写的源代码转换成本地代码的程序称为编译器。每个编写源代码的编程语言都需要其专用的编译器。将C语言编写的源代码转换成本地代码的编译器称为C编译器。编译器首先读入代码的内容,然后再把源代码转换成本地代码。编译器中好像有一个源代码同本地代码的对应表但实际上,仅仅靠对应表是无法生成本地代码的。读入的源代码还要经过语法解析、句法解析、语义解析等,才能生成本地代码。根据CPU类型的不同,本地代码的类型也不同。因而,编译器不仅和编程语言的种类不同,和CPU的类型也是相关的。因为编译器本身也是程序的一种,所以也需要运行环境。例如,有Windows用的·C编译器、Linux用的C编译器等。还有一种交叉编译器,它生成的是和运行环境中的CPU所使用的本地代码。
编译器转换源代码后,就会生成本地文件。不过,本地文件是无法直接运行的。为了得到可以运行的EXE文件,编译之后还需要进行“链接”处理。使用Borland C++ Compiler5.5来看编译和链接是如何进行。Borland C++的编译器是bcc32.exe这个命令工具。在Windows的命令提示符中,运行下列命令后,由C语言编写的源文件Smaplel.c就会被编译。“-W-c”是用来指定编译Windows用的程序的选项。选项是对编译器的提示,有时也称为“开关”。编译后生成的不是EXE文件,而是扩展名为“。obj”的目标文件。Samplel.c编译后,就生成了Samplel.obj目标文件,此时,还处于未完成状态。把多个目标文件结合,生成1个EXE文件的处理就是链接,运行连接的程序就称为连接器。Borland C++的连接器就是ilink.exe的命令行工具。
链接选项“-Tpe-c-x-aa”是指定生成Windows用的EXE文件的选项。这些选项之后,会指定结合的目标文件。在了解了通过程序的编译及链接来生成EXE文件的机制后,接下来看一下EXE文件的运行机制。EXE文件是作为单独的文件储存在硬盘中的。通过资源管理器找到并双击EXE文件,就会把EXE文件的内容加载到内存中运行。程序加载时会生成栈和堆。栈是用来存储函数内部临时使用的变量,以及函数调用时所使用的参数的内存区域。堆是用来存储程序运行时的任意数据及对象的内存领域。EXE文件中并不存在栈及堆的组。栈和堆需要的内存空间是在EXE文件加载到内存后开始运行时得到分配的。银耳,内存中的程序,就是有用于变量的内存空间、用于函数的内存空间、用于栈的内存空间、用于堆的内存空间这4部分构成的。

浙公网安备 33010602011771号