Title

1-1. 计算机系统漫游

The Lifetim of Hello Program

这一章主要是通过介绍 helloworld 这个程序的生命周期,对计算机系统的主要概念做了一个概述。

hello 程序的生命周期是从一个高级 C 语言程序开始的,因为这种形式能够被人读懂。然而,为了在系统上运行 hello.c 程序,每条 C 语句都必须被其他程序转化为一系列的低级机器语言指令。然后这些指令按照一种称为可执行目标程序的格式打好包,并以二进制磁盘文件的形式存放起来。目标程序也称为可执行目标文件。

The Hello Program

首先,我们看一下这个 hello 程序,非常简单的一个打印输出的程序,源代码编写完成之后,保存得到一个后缀名为 .c 的文件 -- hello.c。

#include <stdio.h>

int main()
{
  printf("hello,world\n");
  return 0;
}

The Compilation System

在 Unix 系统上,从源文件到目标文件的转化是由编译器驱动程序完成的∶

linux> gcc -o hello hello.c

敲下回车键,刚才我们编写的 hello.c 经过编译系统(gcc)之后,就会生成一个可执行程序 -- hello。这个过程虽然是通过一条命令来完成的,然而实际上编译系统的处理过程确实非常复杂的。

大致可样分为四个阶段,分别为预处理、编译、汇编以及链接,像下图:

  • 预处理阶段: 预处理器(cpp)根据以字符 # 开头的命令,修改原始的 C 程序。比如 hello.c 中第 1 行的#include <stdio.h>命令告诉预处理器读取系统头文件 stdio.h 的内容,并把它直接插入程序文本中。结果就得到了另一个 C 程序,通常是以 .i 作为文件扩展名。
  • 编译阶段: 这一阶段包括词法分析、语法分析、语义分析、中间代码生成以及优化等等一些列的中间操作。编译器(cc1)将文本文件 hello.i 翻译成文本文件 hello.s,它包含一个汇编语言程序。该程序包含函数 main 的定义,如下所示∶
    main:
      subq $8, %rsp
      movl $.LC0, %edi
      call puts
      movl $0, %eax
      addq $8, %rsp
      ret
    
  • 汇编阶段: 接下来,汇编器(as)根据指令集将汇编程序 hello.s 翻译成机器指令,并且把这一系列的机器指令按照固定的规则进行打包,得到可重定位目标文件 -- hello.o。hello.o 文件是一个二进制文件。
  • 链接阶段: 请注意,hello 程序调用了 printf 函数,它是每个 C 编译器都提供的标准 C 库中的一个函数。printf 函数存在于一个名为 printf.o 的单独的预编译好了的目标文件中,而这个文件必须以某种方式合并到我们的 hello.o 程序中。链接器(ld)就负责处理这种合并。结果就得到 hello 文件,它是一个可执行目标文件(或者简称为可执行文件),可以被加载到内存中,由系统执行。

接下来我们来思考一下,在集成开发环境中(VScode)点一下按钮不香吗?为什么要去抠这个过程呢?接下来我们看一下,为什么要理解编译系统是如何工作的?

  • 第一:理解编译系统可以优化程序的性能。
  • 第二:理解编译系统可以帮助我们理解链接过程中出现的错误。
  • 第三:避免安全漏洞。

reference

CS中文课程

posted on   松—松  阅读(0)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示

目录导航