《程序是怎样跑起来的》——第8章 从源文件到可执行文件

一、代码
1、源代码完成后,就可以编译生成可执行文件了。负责实现该功能的是编译器
2、代码运行:计算机只能运行本地代码。
3、源代码和源文件:用某种编程语言编写的程序就称为源代码,保存源代码的文件称为源文件。
(这里的“源代码”用英文表示是“source code”。source有“原始的”的意思,因此所谓源代码,就是原始的代码。源代码有时也称为源程序。)
示例:转换成本地代码后就变成了同样的语言

对CPU来说,母语就是机器语言,而转换成机器语言的程序就是本地代码。即使是用不同编程语言编写的代码,转换成本地代码后,也都变成用同一种语言(机器语言)来表示了。
4、本地代码:计算机指令也是数值的罗列。这就是本地代码。
示例:本地代码的真面目是数值的罗列

二、编译器
1、编译器的含义:能够把C语言等高级编程语言编写的源代码转换成本地代码的程序称为编译器。每个编写源代码的编程语言都需要其专用的编译器。将C语言编写的源代码转换成本地代码的编译器称为C编译器。
2、编译器种类:因为编译器本身也是程序的一种,所以也需要运行环境。例如,有Windows用的C编译器、Linux用的C编译器等。此外,还有一种交叉编译器,它生成的是和运行环境中的CPU不同的CPU所使用的本地代码。
3、示例:同样的源代码可以转换成适用于不同处理器的本地代码

4、确定编译器种类的三个关键词:C语言、x86系CPU、Windows。
三、文件
1、文件的生成和运行:
编译器转换源代码后,就会生成本地文件。不过,本地文件是无法直接运行的。为了得到可以运行的EXE文件,编译之后还需要进行“链接”处理。下面,就让我们使用Borland C++Compiler5.5(以下称为Borland C++)来看一下编译和链接是如何进行的。

  Borland C++的编译器是bcc32.exe这个命令行工具。在Windows的命令提示符”中,运行下列命令后,由C语言编写的源文件Smaplel.c就会被编译。

  bcc32 -W -c Samplel.c

  “-W-c”是用来指定编译Windows用的程序的选项。选项是对编译器的指示。有时也称为“开关”。

①命令行工具指的是在Windows的命令提示符下使用的CUI程序。
②编译Samplel.c后,可能会出现WinMain的参数没有被用到的警告提示,不过这不会造成什么影响。由于警告并不是出错,因而也可以生成目标文件。
2、编译后生成的不是EXE文件,而是扩展名为“.obj”的目标文件“。Samplel.c编译后,就生成了Samplel.obj目标文件(目标文件(object file)中的object一词,指的是编译器生成结果的意思。和面向对象编程(object oriented programming)的object没有任何关系。面向对象编程的对象指的是数据和处理的集合体。)。虽然目标文件的内容是本地代码,但却无法直接运行。
把多个目标文件结合,生成1个EXE文件的处理就是链接,运行连接的程序就称为链接器(linkage editor或连结器)。Borland C++的链接器就是ilink32.exe的命令行工具。在Windows命令提示符下运行以下命令后,程序所需的目标文件就会被全部链接生成Samplel.exe这个EXE文件。
示例:链接器的错误信息

该错误消息表示的是无法解析Samplel.obj参照的外部符号。外部符号是指其他目标文件中的变量或函数。sprintf及MessageBoxA是目标文件中sprintf()及MessageBox()的名称。
3、Windows中的编译和链接机制

4、链接后的EXE文件的构造

四、程序加载时会生成栈和堆
1、EXE文件的内容分为再配置信息、变量组和函数组,除此之外还会额外生成两个组,那就是栈和堆。栈是用来存储函数内部临时使用的变量(局部变量”),以及函数调用时所用的参数的内存区域。堆是用来存储程序运行时的任意数据及对象的内存领域。
2、EXE文件中并不存在栈及堆的组。栈和堆需要的内存空间是在EXE文件加载到内存后开始运行时得到分配的。因而,内存中的程序,就是由用于变量的内存空间、用于函数的内存空间、用于栈的内存空间、用于堆的内存空间这4部分构成的。
示例:加载到内存的程序由4部分构成

①不管是什么程序,程序的内容都是由处理和数据构成的。大多数编程语言都是用函数来表示处理、用变量来表示数据。
②栈和堆的大小,可以由程序员任意指定。在高级编程语言中,编译器会自动生成指定栈和堆大小的代码,并将其附加到程序中。

posted @ 2024-02-21 19:35  加克  阅读(8)  评论(0编辑  收藏  举报