目录
简单编译原理
前言
学习杜老师推荐的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到执行的四个阶段即预处理阶段、编译阶段、汇编阶段以及链接阶段。