Makefile第二课:简单编译原理

简单编译原理

前言

学习杜老师推荐的Makefile教程视频,链接。记录下个人学习笔记,仅供自己参考。

之前有转载过杜老师的从零Makefile落地算法大项目文章,感兴趣的可以看看。

本课程为第二课,主要讲解计算机简单编译原理

1.hello world在计算机的表示

hello 程序的生命周期是从一个源程序(或者说源文件)开始的,即程序员通过编辑器创建并保存的文本文件,文件名是 hello.c。源程序实际上就是一个由值 0 和 1组成的位(又称为比特)序列,8 个位被组织成一组,称为字节。每个字节表示程序中的某些文本字符

大部分计算机使用 ASCII 标准来表示文本字符

  • 用一个唯一的单字节大小的整数值息来表示每个字符
  • hello.c 程序是以字节序列的方式储存在文件中的

hello.c 的表示方法说明了一个基本思想∶ 系统中所有的信息——包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传送的数据,都是由一串比特表示的

在这里插入图片描述

2.编译过程

hello 程序的生命周期从一个高级 C 语言程序开始

为了在系统上运行 hello.c 程序,每条 C 语句都必须被其他程序转化为一系列的低级机器语言指令

然后这些指令按照一种称为可执行目标程序的格式打好包,并以二进制磁盘文件的形式存放起来

GCC 编译器读取源程序 hello.c,并把它翻译成一个可执行目标文件 hello。这个翻译过程可分为四个阶段完成,如下图所示

执行这四个阶段的程序(预处理器、编译器、汇编器和链接器)一起构成了编译系统(compilation system)

在这里插入图片描述

2.1 预处理阶段

预处理器(cpp)根据以字符#开头的命令,修改原始的C程序。比如hello.c中第1行的#include<stdio.h>命令告诉预处理读取系统头文件stdio.h的内容,并把它直接插入程序文本中。结果就得到了另一个C程序,通常是以.i作为文件扩展名

2.2 编译阶段

编译器(ccl)将文本文件hello.i翻译成文本文件hello.s,它包含一个汇编语言程序。该程序包含函数main的定义,如下所示:

            main:
            subq    $8, %rsp 
            mov1    $.LCO,%edi 
            call    puts 
            mov1    $0,%eax 
            addq    $8,%rsp 
            ret

每条语句都以一种文本格式描述了一条低级机器语言指令。汇编语言非常有用,它为不同高级语言的不同编译器提供了通用的输出语言。

2.3 汇编阶段

汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序(relocatable object program)的格式,并将结果保存在目标文件hello.o中。

hello.o文件是一个二进制文件,它包含的17个字节是函数main的指令编码。如果我们在文本编辑器中打开hello.o文件,将看到一堆乱码。

2.4 链接阶段

注意,hello程序调用了printf函数,它是每个C编译器都提供的标准C库中的一个函数。printf函数存在于一个名为printf.o的单独预编译好的目标文件中,而这个文件必须以某种方式合并到我们的hello.o程序中。

链接器(ld)就负责处理这种合并。结果就得到了hello文件,它是一个可执行目标文件(简称为可执行文件),可以被加载到内存中,由系统执行。

3.hello world的执行过程

3.1 第一步

  • shell 等待我们输入一个命令
  • 当我们在键盘上输入字符串"./hello"(注意这里是编译好的可执行目标文件)后
  • shell 程序将字符逐一读入寄存器
  • 再把它存放到内存中

在这里插入图片描述

3.2 第二步

  • 当我们在键盘上敲回车键时,shell 程序就知道我们已经结束了命令的输人
  • 然后 shell 执行一系列指令来加载可执行的 hello 文件
  • 这些指令将 hello 目标文件中的代码和数据从磁盘复制到主存
  • 数据包括最终会被输出的字符串"hello,world\n"。

在这里插入图片描述

3.3 第三步

  • 一旦目标文件 hello 中的代码和数据被加载到主存
  • 处理器就开始执行 hello 程序的 main 程序中的机器语言指令
  • 这些指令将 “hello,world\n” 字符串中的字节从主存复制到寄存器文件
  • 再从寄存器文件中复制到显示设备,最终显示在屏幕上

在这里插入图片描述

4.程序在计算机内的存储

上面的例子揭示了一个重要的问题,即系统“似乎”花费了大量的时间和步骤把信息从一个地方挪到另一个地方

  • hello程序的机器指令最初是存放在磁盘上
  • 当程序加载时,它们被复制到主存
  • 当处理器运行程序时,指令又从主存复制到处理器

相似地,数据串 "hello,world\n"开始时在磁盘上,然后被复制到主存,最后从主存上复制到显示设备

总结

本次课程主要掌握了从code到执行的四个阶段即预处理阶段、编译阶段、汇编阶段以及链接阶段。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱听歌的周童鞋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值