helloworld经历了什么?

《深入理解计算机系统》学习笔记

hello world往往是学习编程时遇到的第一个示例,下面是一个C语言版本:

#include <stdio.h>

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

这个程序会在终端打印hello, world这串字符,那么这个程序在我们的计算机上到底是怎能被读取运行的呢?

程序的存储

我们将这段代码保存为文本文件并命名为hello.c,称作源程序或源文件。这段代码里都是英文字母以及一些符号,然而,计算机内存储的信息都是二进制的,计算机只能识别由10组成的位(比特)序列,每8个位组成一个字节。那么英语有26个字母,汉字更是成千上万个,只用0和1怎么表示呢?不用怕,我们只要将很多个0与1排列组合一下就能表示很多个了,n位就能表示2n个文字。例如一个字节8位最多就能表示256个。这就是编码的强大能力了,常见的编码标准有ASCII和UTF-8。
ascii低128位对照表

程序被翻译成不同格式

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。可以被加载到内存由系统执行。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章