1.1 Information Is Bits + Context
这一小节内容很简单,以
#include <stdio.h>
int main()
{
printf("hello, world\n");
return 0;
}
这段hello world代码开始(瞬间把我带回了大一上C++编程课的日子)
介绍了存储这段代码的text file是由一系列bit构成,每8个bit组成一个byte。
大多计算机使用ASCII码表示text file里面的每个字符,一个ASCII码由一个byte大小的整数值表示。
原文有这么一句话表述计算机(或网络中传输的信息)都是由一串bit表示的:
The representation ofhello.cillustrates a fundamental idea: All information in a system—including disk files, programs stored in memory, user data stored in memory, and data transferred across a network—is represented as a bunch of bits.
我们只能通过这串bit的上下文(context)关系来区分不同的信息。
---------------------------------------------------------------------------
1.2 Programs Are Translated by Other Programs into Different Forms
上文的hello.c是一种人能看明白的高级语言,但为了能够在电脑上跑起来,需要把这种高级语言转化成低级的机器指令(machine-language instructions)。然后把机器指令打包成可执行对象程序/可执行对象文件(executable object program/executable object files),以二进制的方式存到盘里。
书中以Unix系统为例,画出了从hello.c到可执行目标程序的转化路程。
图中是通过四个步骤,把hello.c编成了hello,下面对四个步骤逐个介绍。
第一步Preprocessing:
cpp根据#字符后面的指令修改原始的C程序,这里就是以# include <stdio.h>进行修改。这玩意告诉cpp读取系统头文件stdio.h的内容,然后直接把它插入到程序文本中,这就得到了hello.i。
第二步Compilation:
cc1翻译了hello.i的文本,得到hello.s,这个hello.s的内容是这样子的
就是个汇编语言(assembly-language),2-7的每行都描述(describe)了一个低级的机器指令。
第三步Assembly:
as把hello.s翻译成了彻底的机器指令,并打包成一种可定位对象程序(relocatable object program),把结果存到对象文件hello.o中。这个.o文件包含17个字节,用于编码main函数里的指令。
第四步Linking:
注意到hello程序调用了printf函数,这个printf是C标准库里的,每个C编译器都会提供。这个printf函数预存放在一个单独的预编译对象文件printf.o中。链接器把hello.o和printf.o文件给Merge起来,得到hello文件。这个hello就是一个准备好加载到内存里并且执行的可执行对象文件。