计算机系统初印象

149 阅读4分钟

这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战

前言

作为新时代的程序员,我们站在巨人的肩膀上,享受着前辈们探索的福利。这虽然是一个好事,但是也潜藏着一定的坏处,这让我们不会去关心计算机系统或者说计算机底层是如何帮我们进行编译代码,执行代码的过程,我们依赖IDE给我们的提示以及快捷输入。只需要点击Run按钮,得到对应的结果相应就可以了。所以,我们还是要注重基础知识的补充,万变不离其宗,我们就可以以不变应万变的。

位表示(字节序列)

计算机的本质就是0和1组成的位表示,所有的源程序都是0和1的位组成的,典型的计算机架构由8个位组成,称做字节。每个字节可以表示程序中的文本字符。文本与字符的映射关系由字符编码集设置,计算机最基础的编码集是ASCII编码集,还有UTF-8,GBK等编码,在我自己的Mac系统上通过以下命令:man ascii即可查看ASCII码的编码集的。

image.png

文本文件:由ASCII码字符构成的文件称为文本文件
二进制文件:所有除文本文件以外的文件,统一称为二进制文件。 所以我们常用的Linux系统,才被称为由文件组成的系统。

那么我们的位表示,也就是1和0组成的字节序列。它们是如何在计算机上工作的?当然需要结合上下文来判定,比如1001这个序列,它在无符号整数的上下文中,表示的数值是9,但是我们把它放到有符号整数的上下文中,它表示的数值变为-7,然而再把它放到机器指令中,它又代表其他的含义。 这就是字符序列加上某种解释方式,形成一个它具有的含义。

程序编译

通过上面的段落。了解到了源程序文本字符就是一组组的字节序列组成的。那么计算机是怎么回明白我编写的代码想要做什么呢。它只认识1和0的字节序列呀。这就是要涉及编译系统的概念了。所谓的编译系统就是把程序员写的代码,转变成计算机能明白的语言(也就是所谓的机器指令),比如,我在和一个美国人聊天,在我不懂英语的情况下,我需要一个“编译系统”(也就是翻译软件或者一个翻译官),替我将我的中文转换为英文,输出给这个美国人,这个美国人才明白我想要跟他交流的目的。所以编译系统就承担这中间转换的作用。
编译的过程大致分为以下的步骤(以C语言作为例子)

源程序文本 -> 预处理器(cpp) -> 编译器(ccl) -> 汇编器(as) -> 链接器(ld) -> 可执行目标文件

预处理阶段:与处理器根据以字符#开头的命令,修改原是的C语言程序,生成另一个C语言程序,以i作为文件的扩展名
编译阶段:编译器将文本文件xxx.i翻译成xxx.s的文本文件,它包含一个汇编语言程序。
汇编阶段:汇编器将xxx.s文本文件,翻译成机器语言指令,把这些指令打包成一种可叫做可重定位目标程序(relocatable object program)的格式,生成xxx.o文件,它是一个二进制文件。
链接阶段:假设我代码里面,有调用了C标准库的函数,例如printf函数,该函数位于单独编译好的printf.o文件中,这个文件必须以某种方式合并到xxx.o文件中,链接器就是负责处理这种合并的。结果就得到ooo文件,它是一个可执行目标文件(或者简称为可执行文件),可以被加载到内存中,由系统执行。

结论

今天,我们初步了解了,计算机系统中的本质表示字节序列,以及对于一个程序是如何执行起来的大概印象。