📜  编译C程序:-幕后

📅  最后修改于: 2021-05-29 12:39:00             🧑  作者: Mango

C是一种中级语言,它需要编译器才能将其转换为可执行代码,以便程序可以在我们的计算机上运行。

我们如何编译和运行C程序?
以下是我们在具有gcc编译器的Ubuntu计算机上使用的步骤。

汇编

  • 我们首先使用编辑器创建一个C程序,然后将文件另存为filename.c
$ vi filename.c
  • 右图显示了一个将两个数字相加的简单程序。

编译31

  • 然后使用以下命令进行编译。
$ gcc –Wall filename.c –o filename
  • 选项-Wall启用所有编译器的警告消息。建议使用此选项来生成更好的代码。
    选项-o用于指定输出文件名。如果我们不使用此选项,那么将生成名称为a.out的输出文件。

编译21

  • 编译可执行文件生成后,我们使用以下命令运行生成的可执行文件。
$ ./filename 

编译过程中有什么内容?
编译器将C程序转换为可执行文件。 C程序成为可执行文件有四个阶段:

  1. 前处理
  2. 汇编
  3. 集会
  4. 连结中

通过执行以下命令,我们将获得当前目录中的所有中间文件以及可执行文件。

$gcc –Wall –save-temps filename.c –o filename 

以下屏幕快照显示了所有生成的中间文件。

编译4

让我们一个个地看看这些中间文件包含什么。

前处理

这是传递源代码的第一阶段。此阶段包括:

  • 删除评论
  • 扩展宏
  • 扩展包含的文件。
  • 条件编译

预处理后的输出存储在filename.i中。我们来看一下filename.i的内容:使用$ vi filename.i
在上面的输出中,源文件充满了很多信息,但是最后保留了我们的代码。
分析:

  • 现在printf包含a + b而不是add(a,b),这是因为宏已扩展。
  • 评论被剥离。
  • #include 丢失了,相反,我们看到了很多代码。因此头文件已被扩展并包含在我们的源文件中。

编译中

下一步是编译filename.i并生成一个;中间编译输出文件filename.s 。该文件在汇编级说明中。让我们使用$ vi filename.s浏览该文件

图像

快照显示它是汇编语言可以理解的汇编语言。

集会
在此阶段,将filename.s用作输入,并由汇编程序将其转换为filename.o 。该文件包含机器级别的说明。在此阶段,仅将现有代码转换为机器语言,诸如printf()之类的函数调用无法解析。让我们使用$ vi filename.o查看此文件

编译7

连结中

这是最后一个阶段,在此阶段中完成了所有函数调用及其定义的链接。链接器知道所有这些功能的实现位置。 Linker还会做一些额外的工作,它会在程序的开始和结束时向我们的程序中添加一些额外的代码。例如,有一个代码需要设置环境,例如传递命令行参数。使用$ size filename.o$ size filename可以轻松地验证此任务。通过这些命令,我们知道输出文件如何从目标文件增加到可执行文件。这是因为链接器在我们的程序中添加了额外的代码。

编译8