深入理解计算机系统之计算机系统漫游(程序编译)

计算机系统是由硬件和软件组成的,所有计算机都有相似的硬件和软件组件,他们又执行着相似的功能。只有深入了解这些组件是如何影响程序的正确性和性能的,很大程度上来提升提高程序员的技能水平。

我们以世界万能程序大法hello为例,跟踪hello程序的生命周期开始深入系统。
hello程序(C语言):

#include<stdio.h>

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

1. 信息就是位+上下文

hello程序的生命周期是从源程序(源文件)开始的,文件名为hello.c。大部分的现代计算机系统都使用ASCII标准来表示文本字符,hello.c的ASCII表示如下:
在这里插入图片描述
这里注意:每个文本行都是以一个看不见的换行符\n结束的,像hello.c这样只有ASCII字符构成的文件称为文本文件,所有其他文件都称为二进制文件

此表示方法说明了一个基本思想:
系统中的所有信息——包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传送的数据,都是由一串比特表示的。 区分不同数据对象的唯一方法使我们读到这些数据对象时的上下文。

作为程序员和学习编程,我们需要了解数字的机器表示——他们是对真值的有限近似值。

2. 程序被编译的过程

hello程序被翻译成低级机器语言指令,以一种可执行目标程序(可执行目标文件)的格式打包,以二进制磁盘文件存放。

编译过程分为四个阶段,如下:
在这里插入图片描述
预处理阶段(添加头文件)——编译阶段(翻译成汇编程序)——汇编阶段(翻译成机器语言指令)——链接阶段(合并调用)

结果就得到hello文件,可以被加载到内存中,由系统执行。

3. 认识编译系统工作原理的必要性

编译系统由上述四部分组成,即预处理器、编译器、汇编器、链接器。那么就有一些重要的原因促使我们去知道编译系统是如何工作的,原因如下:

——优化程序性能
——理解链接时出现的错误
——避免安全漏洞

4. 系统的硬件组成
一个典型系统的硬件组成,如下图所示:
在这里插入图片描述
CPU:中央处理单元, ALU:算术/逻辑单元, PC:程序计数器, USB:通用串行总线

——总线:贯穿整个系统的是一组电子管道,称作总线,它携带信息字节并负责在各个部件间传递。通常总线被设计成传送定长的字节块,也就是字(word)。字中的字节数(即字长)是一个基本的系统参数,要么是4个字节(32 位),要么是8个字节(64位)

——I/O设备:I/O(输人/输出)设备是系统与外部世界的联系通道。示例系统包括四个I/O设备 :作为用户输人的键盘和鼠标,作为用户输出的显示器,以及用于长期存储数据和程序的磁盘驱动器(简单地说就是磁盘)。每个I/O设备都通过一个控制器或适配器与I/O总线相连。 控制器是I/O设备本身或者系统的主印制电路板(通常称作主板)上的芯片组;而适配器则是一块插在主板插槽上的卡。

——主存:主存是一个在处理器执行程序时,用来临时存放程序和程序处理的数据的存储设备。
从物理上来说,主存是由一组动态随机存取存储器(DRAM)芯片组成的。从逻辑上来说,存储器是一个线性的字节数组,每个字节都有其唯一的地址(数组索引),且地址是从零开始的。

——处理器:中央处理单元(CPU ),简称处理器,是解释(或执行)存储在主存中指令的引擎。处理器的核心是一个大小为一个字的存储设备(或寄存器),称为程序计数器(PC)。在任何时刻 ,PC都指向主存中的某条机器语言指令(即含有该条指令的地址)。
从系统通电开始,直到系统断电,处理器一直在不断地执行程序计数器指向的指令,再更新程序计数器,使其指向下一条指令。
CPU在指令的要求下可能会执行这些操作。
加载:从主存复制一个字节或者一个字到寄存器,以覆盖寄存器原来的内容。
存储:从寄存器复制一个字节或者一个字到主存的某个位置,以覆盖这个位置上原来的内容。
操作:把两个寄存器的内容复制到ALU, ALU对这两个字做算术运算,并将结果存放到一个寄存器中,以覆盖该寄存器中原来的内容。
跳转:从指令本身中抽取一个字,并将这个字复制到程序计数器(PC)中,以覆盖PC中原来的值。

5.处理器读取并解释存储在内存中的指令(运行hello程序)

hello.c源程序被编译成可执行目标文件hello后就存放在磁盘上了

在Unix系统上运行需要将文件名hello输入到shell中

linux>./hello
hello,world
linux>

shell是一个命令行解释器,它输出一个提示符(linux>),等待输入一个命令行,如果输出的第一个单词不是一个内置的shell命令,那么shell就会假设这是一个可执行目标文件的名字,加载这个文件。

初始时,shell程序执行他的指令,等待我们输入一个命令行,输入./hello后,shell程序将字符逐一读入寄存器,再把它存放到内存中。
在这里插入图片描述

然后回车键标志结束命令输入,shell就执行一系列指令加载可执行hello文件并将其中的代码和数据从磁盘复制到主存。
利用直接存储器存取(DMA)技术,数据可以不通过CPU就直接从磁盘复制到主存
在这里插入图片描述
一旦目标文件hello中的代码和数据被加载到主存,处理器就开始执行hello程序的 main程序中的机器语言指令。
这些指令将"hello, world!"字符串中的字节从主存复制到寄存器文件,再从寄存器文件中复制到显示设备,最终显示在屏幕上。如下图:
在这里插入图片描述
9. 系统之间利用网络通信

实际上,现代系统通常通过网络和其他系统连接到一起。数据通过网络(视为I/O设备)被复制到另一主机。如下图:
在这里插入图片描述
远端运行hello程序的五个基本步骤如下:

在这里插入图片描述
当我们在talnet客户端输入“hello”字符串并回车后,客户端会将这个字符串发送给talnet服务器,talnet服务器从网络上接收到这个字符串后,会传送给远程的shell程序。
然后shell运行hello程序,并将输出结果返回给talnet服务器。最后talnet服务器通过网络将结果传给talnet客户端,客户端将结果输出到本地终端上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫96

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值