《深入理解计算机系统》学习笔记
hello world往往是学习编程时遇到的第一个示例,下面是一个C语言版本:
#include <stdio.h>
int main()
{
printf("hello, world\n");
return 0;
}
这个程序会在终端打印hello, world
这串字符,那么这个程序在我们的计算机上到底是怎能被读取运行的呢?
程序的存储
我们将这段代码保存为文本文件并命名为hello.c,称作源程序或源文件。这段代码里都是英文字母以及一些符号,然而,计算机内存储的信息都是二进制的,计算机只能识别由1和0组成的位(比特)序列,每8个位组成一个字节。那么英语有26个字母,汉字更是成千上万个,只用0和1怎么表示呢?不用怕,我们只要将很多个0与1排列组合一下就能表示很多个了,n位就能表示2n个文字。例如一个字节8位最多就能表示256个。这就是编码的强大能力了,常见的编码标准有ASCII和UTF-8。
程序被翻译成不同格式
C语言是高级语言,要想在计算机上运行,就必须被翻译成计算机能理解的机器语言指令。然后这些指令按一种称为可执行目标程序的格式打好包,并以二进制磁盘文件的形式存放起来。目标程序也称可执行目标文件。linux> gcc -o hello hello.c
在Linux上我们用GCC将hello.c翻译称可执行文件hello,这个过程可以分为四个阶段。
-
预处理阶段:预处理器cpp根据以井号#开头的预处理命令修改原始程序。例如这里hello.c的第一行
#include <stdio.h>
告诉预处理器读取头文件stdio.h的内容(这个文件里包含了printf
这个函数)并把它插入源程序,得到hello.i
。 -
编译阶段:编译器ccl将
hello.i
翻译成文本文件hello.s
,这里包含一个汇编语言程序:
main:
subq $8, %rsp
movl $LC0, %edi
call puts
movl $0, %eax
addq $8, %rsp
ret
-
汇编阶段:汇编器as将hello.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存到
hello.o
-
链接阶段:我们在程序里用到了
printf
函数,它存在于一个名为printf.o
的预编译好了的文件中。这个文件需要以某种方式合并到我们的程序中,这就要用到链接器ld。结果就得到可执行文件hello
。可以被加载到内存由系统执行。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。