---
title: 计算机硬件核心基础
date: 2020-05-07 10:43:18
tags: 
- 计算机组成
- 计算机硬件
- 操作系统
categories:
- 计算机基础
---

## 前言

先来了解一些基本概念：

**`编程语言`**本质是一门语言，语言就是一种事物与另外一种事物沟通的表达方式/工具，那么编程语言就是**人**与**计算机**之间沟通的方式。

<!--more-->

**`编程`**就是人类把自己想让计算机做的事，也就是自己的思维逻辑，用编程语言表达出来。

**`编程的目的`**就是让计算机按照人类的思维逻辑去工作，从而解放人力。

![1](https://i.loli.net/2020/05/07/hg3NOqwCmSMkfGj.jpg)

## 计算机组成原理

> ![简单计算机组件](https://i.loli.net/2020/05/16/Hr8qJpKlM3tcuIi.jpg)

### 计算机五大组成部分

#### **`控制器`**

**控制器**是计算机的指挥系统。控制器通过地址访问存储器，从存储器中取出指令，经译码器分析后，根据指令分析结果产生相应的操作控制信号作用于其他部件，使得各部件在控制器控制下有条不紊地协调工作。



#### **`运算器`**

**运算器**是实现算术运算和逻辑运算的部件。

**`控制器 + 运算器 = CPU`** 

#### **`存储器`**

**存储器**是计算机用来存放所有数据和程序的记忆部件。它的基本功能是按指定的地址存（写）入或者取（读）出信息。 

计算机中的存储器可分成两大类：一类是内存储器，简称**内存或主存**；另一类是外存储器(辅助存储器)，简称**外存或辅存**。 存储器由若干个存储单元组成，每个存储单元都有一个地址，计算机通过地址对存储单元进行读写。一个存储器所包含的字节数称为**存储容量**，单位有B、KB、MB、GB、TB等。

* **内存:** 存取数据快；断电数据丢失，只能临时存取数据。

* **外存:**存取数据慢；断电数据不会丢失，用来永久保存数据 。

	内存的存取速度要远高于外存。

#### **`输入设备input`**

**输入设备**是计算接收外界输入数据的工具，如键盘、鼠标。

#### **`输出设备output`**

**输出设备**是计算机向外输出数据的工具，如显示器、打印机。

存储器如内存、磁盘等既是输入设备又是输出设备，统称为IO设备

> ![img](https://i.loli.net/2020/05/16/4aDRbLGvfy7wrAs.png)

CPU存取的数据和指令都来自主存储器(内存) 。

内存称之为主存，主存储器内的数据则是从输入单元所传输进来！而CPU处理完毕的数据也必须先写回主存储器中，最后数据才从主存储器传输到输出单元。

### 程序运行与三大核心硬件(CPU 内存 硬盘)的关系

我们编写的程序一定是要运行于计算机硬件之上，而站在硬件的角度，与运行程序有关的三大核心硬件为CPU、内存、硬盘。

程序最先是存放于硬盘中的，程序的运行是先从硬盘把代码加载到内存中，然后CPU是从内存中读取指令运行。

## 操作系统

### 操作系统的由来

大前提：我们编程目的就是为了奴役计算机，让计算机硬件自发地运行起来，然而硬件毕竟是”死的“，**硬件的运行都是由软件支配**。

倘若我们要开发一个应用程序，在没有操作系统之前，开发者在编写业务逻辑之前，必须先编写一套完整的控制程序来控制所有的硬件基本运行(这要求开发者需要详细了解计算机硬件的各种控制细节，例如要熟悉CPU里面所有的指令集)，如此，所有开发者在开发程序时都必须按以下两个步骤：

```tex
1.编写一套完整的的控制程序，用来控制硬件的基本运行，以及把复杂的硬件的操作封装成简单的接口
2.基于控制程序的接口开发包含一系列业务逻辑的程序，为了与控制程序区分，可以称为应用程序.
```

综上，对于不同的应用程序来说，应用程序的业务逻辑各不相同，但硬件的控制程序都大致相同，为了避免所有开发者做重复劳动，以及不用再耗费精力去了解所有硬件的运行细节，有公司专门跳出来承担起控制程序的开发任务，这里所说的控制程序指的就是操作系统。

**`操作系统`**是一个协调、管理、控制计算机硬件资源与应用软件资源的控制程序。它位于计算机硬件与应用软件之间，起承上启下的作用。

**操作系统的功能:** 

* 控制计算机硬件的基本运行

* 帮我们把复杂的硬件的控制封装成简单的接口，对于开发应用程序来说只需要调用操作系统提供给我们的接口即可

	

### 系统软件与应用软件

* 系统软件：

	指控制和协调计算机及外部设备、支持应用软件开发和运行的系统，是无需用户干预的各种程序的集合，主要功能是调度、监控和维护计算机系统；负责管理计算机系统中各种独立的硬件，使得它们可以协调工作。系统软件使得计算机使用者和其他软件将计算机当作一个整体而不需要顾及到底层每个硬件是如何工作的。

	一般来讲，系统软件包括操作系统和一系列基本的工具（比如编译器，数据库管理，存储器格式化，文件系统管理，用户身份验证，驱动管理，网络连接等方面的工具），是支持计算机系统正常运行并实现用户操作的那部分软件。

* 应用软件：

	应用软件(Application）是和系统软件相对应的，是用户可以使用的各种程序设计语言，以及用各种程序设计语言编制的应用程序的集合，分为应用软件包和用户程序。应用软件包是利用计算机解决某类问题而设计的程序的集合，多供用户使用。

	应用软件是为满足用户不同领域、不同问题的应用需求而提供的那部分软件。 它可以拓宽计算机系统的应用领域，放大硬件的功能。

### 计算机系统三层结构

我们开发应用程序本质是在控制硬件，但是我们直接打交道的是操作系统，应用程序都是通过操作系统来间接地操作硬件的，所以一套完整的计算机系统分为三层，如下：

> ![计算机系统三层结构](https://i.loli.net/2020/04/20/nrdy8V6NIoPLhiD.jpg)

### 平台与跨平台的概念

应用程序都是运行于操作系统之上，而操作系统则是运行于硬件之上的，所以承载应用程序的是一台运行有操作系统的计算机，称之为应用程序的运行平台，即：**`硬件 + 操作系统 = 平台`**。

> ![平台](https://i.loli.net/2020/04/20/iBWhvPRqGZ14ry5.jpg)

常见的平台有：windows系统+某款硬件、linux系统+某款硬件、ubuntu+某款硬件等，我们在开发应用程序时就需要考虑到应用程序的**跨平台**性，如果能开发出一款可以在任意平台运行的应用程序，那对于开发者来说真是极大的福音。

跨平台即不依赖于操作系统，也不依赖硬件环境。一个操作系统下开发的应用，放到另一个操作系统下依然可以运行。而决定应用软件的跨平台性的关键因素往往是编程语言的选择,一般解释型语言(即不需编译的语言，比如：PHP、Python等)都可跨平台运行；有些编译型语言(如：Java等)由于其本身的特性(不同平台有不同的库、具有跨平台的扩展以及中间件)，也可跨平台运行。

## 知识拓展

### CPU详解

#### CPU的分类与指令集

CPU内部是含有微指令集的，我们所使用的的软件都要经过CPU内部的微指令集来完成才行。这些指令集的设计主要又被分为两种设计理念，这就是目前世界上常见到的两种主要的CPU种类：分别是精简指令集（RISC）与复杂指令集（CISC）系统。下面我们就来谈谈这两种不同CPU种类的差异！

1.**`精简指令集`**

精简指令集(Reduced Instruction Set Computing，RISC)：这种CPU的设计中，微指令集较为精简，每个指令的运行时间都很短，完成的动作也很单纯，指令的执行效能较佳；但是若要做复杂的事情，就要由多个指令来完成。常见的RISC指令集CPU主要例如Sun公司的SPARC系列、IBM公司的Power Architecture（包括PowerPC）系列、与ARM系列等。【注：Sun已经被Oracle收购】

SPARC架构的计算机常用于学术领域的大型工作站中，包括银行金融体系的主服务器也都有这类的计算机架构；

PowerPC架构的应用，如Sony出产的Play Station 3（PS3）使用的就是该架构的Cell处理器。

ARM是世界上使用范围最广的CPU，常用的各厂商的手机、PDA、导航系统、网络设备等，几乎都用该架构的CPU。

2.**`复杂指令集`**

复杂指令集（Complex Instruction Set Computer，CISC）与RISC不同，在CISC的微指令集中，每个小指令可以执行一些较低阶的硬件操作，指令数目多而且复杂，每条指令的长度并不相同。因此指令执行较为复杂所以每条指令花费的时间较长，但每条个别指令可以处理的工作较为丰富。常见的CISC微指令集CPU主要有AMD、Intel、VIA等的x86架构的CPU。
    

总结：

CPU按照指令集可以分为精简指令集CPU和复杂指令集CPU两种，区别在于前者的指令集精简，每个指令的运行时间都很短，完成的动作也很单纯，指令的执行效能较佳；但是若要做复杂的事情，就要由多个指令来完成。后者的指令集每个小指令可以执行一些较低阶的硬件操作，指令数目多而且复杂，每条指令的长度并不相同。因为指令执行较为复杂所以每条指令花费的时间较长，但每条个别指令可以处理的工作较为丰富。

#### x86-64

**``x86架构``**

x86是针对cpu的型号或者说架构的一种统称，详细地讲，最早的那颗Intel发明出来的CPU代号称为8086，后来在8086的基础上又开发出了80285、80386....，因此这种架构的CPU就被统称为x86架构了。

由于AMD、Intel、VIA所开发出来的x86架构CPU被大量使用于个人计算机上面，因此，个人计算机常被称为x86架构的计算机！

程序员开发出的软件最终都要翻译成cpu的指令集才能运行，因此软件的版本必须与cpu的架构契合，举个例子，我们在MySQL官网下载软件MySQL时名字为：``Windows(x86,32-bit),ZIP Archive (mysql-5.7.20-win32.zip)``我们发现名字中有x86，这其实就是告诉我们：该软件应该运行在x86架构的计算机上。

**``64位 ``**

cpu的位数指的是cpu一次性能从内存中取出多少位二进制指令，64bit指的是一次性能从内存中取出64位二进制指令。

在2003年以前由Intel所开发的x86架构CPU由8位升级到16、32位，后来AMD依此架构修改新一代的CPU为64位，到现在，个人计算机CPU通常都是x86_64的架构。

cpu具有向下兼容性，指的是64位的cpu既可以运行64位的软件，也可以运行32位的软件，而32位的cpu只能运行32位的软件。这其实很好理解，如果把cpu的位数当成是车道的宽，而内存中软件的指令当做是待通行的车辆，宽64的车道每次肯定既可以通行64辆车，也可以通信32辆车，而宽32的车道每次却只能通行32辆车

#### 运算器与控制器

常将运算器和控制器合称为中央处理器(Central Processing Unit，CPU)。其中运算器用来主要负责程序运算与逻辑判断，控制器则主要协调各组件和各单元的工作，所以CPU的工作主要在于管理和运算。可以说计算机的大脑就是CPU。

**`1.运算器`**

运算器是对信息进行处理和运算的部件。经常进行的运算是算术运算和逻辑运算，所以运算器又可称为算术逻辑运算部件（Arithmetic and Logical，ALU）。

运算器的核心是加法器。运算器中还有若干个通用寄存器或累加寄存器，用来暂存操作数并存放运算结果。寄存器的存取速度比存储器的存放速度快很多。

**`2.控制器`**

控制器是整个计算机的指挥中心，它的主要功能是按照人们预先确定的操作步骤，控制整个计算机的各部件有条不紊的自动工作。

控制器从主存中逐条地读取出指令进行分析，根据指令的不同来安排操作顺序，向各部件发出相应的操作信号，控制它们执行指令所规定的任务。控制器中包括一些专用的寄存器。

#### 寄存器

寄存器是中央处理器内的组成部份。它跟CPU有关。寄存器是有限存贮容量的高速存贮部件，它们可用来暂存指令、数据和位址。在中央处理器的控制部件中，包含的寄存器有指令寄存器(IR)和程序计数器(PC)。在中央处理器的算术及逻辑部件中，包含的寄存器有累加器(ACC)。

> ![img](https://i.loli.net/2020/05/16/l1qb8EsJoZPtx4m.jpg)

#### 内核态与用户态

除了在嵌入式系统中的非常简单的CPU(如:单片机)之外，多数CPU都有两种模式，即**`内核态与用户态`**。

通常，计算机由[PSW](https://baike.baidu.com/item/PSW/1878339?fr=aladdin)(程序状态寄存器)控制这两种模式。

**`内核态：`**当cpu在内核态运行时，cpu可以执行指令集中所有的指令，很明显，所有的指令中包含了使用硬件的所有功能，（操作系统在内核态下运行，从而可以访问整个硬件）

**`用户态：`**用户程序在用户态下运行，仅仅只能执行cpu整个指令集的一个子集，该子集中不包含操作硬件功能的部分，因此，一般情况下，在用户态中有关I/O和内存保护（操作系统占用的内存是受保护的，不能被别的程序占用），当然，在用户态下，将PSW中的模式设置成内核态也是禁止的。

**`内核态与用户态切换:`**
		用户态下工作的软件不能操作硬件，但是我们的软件一定会有操作硬件的需求，比如从磁盘上读一个文件，那就必须经历从用户态切换到内核态的过程，为此，用户程序必须使用[系统调用(system call)](https://baike.baidu.com/item/系统调用/861110)，通过相应的指令把用户态切换成内核态。

把系统调用看成一个特别的过程调用指令就可以了，该指令具有从用户态切换到内核态的特别能力。

#### 多线程与多核芯片

在一个CPU中增加多个处理逻辑，称为多线程或超线程，该概念是由Inter公司首次提出。

多核就是多个完整的CPU处理器。

比如，我们常说的四核八线程，就是指有四个CPU,每个CPU中有两个线程。

> <img src="https://i.loli.net/2020/05/03/L4eNdiVUZ3AYOgs.png" alt="1" style="zoom: 80%;" />
>
> <img src="https://i.loli.net/2020/05/03/Ix8Ogqi9DKUa36H.png" alt="2" style="zoom:80%;" />



### 存储器相关

> ![存储层次结构](https://i.loli.net/2020/05/16/Ko49glFa7BZUNXV.jpg)

存储器系统采用如上图的分层结构，顶层的存储器速度较高，容量较小，与底层的存储器相比每位的成本较高，其差别往往是十亿数量级的。

#### 寄存器即L1缓存

用与cpu相同材质制造，与cpu一样快，因而cpu访问它无时延，典型容量是：在32位cpu中为32\*32，在64位cpu中为64\*64，在两种情况下容量均小于1KB。

#### 高速缓存即L2缓存

主要由硬件控制高速缓存的存取，内存中有高速缓存行按照0\~64字节为行0，64~127为行1…

最常用的高速缓存行放置在cpu内部或者非常接近cpu的高速缓存中。当某个程序需要读一个存储字时，高速缓存硬件检查所需要的高速缓存行是否在高速缓存中。如果是，则称为**高速缓存命中**，缓存满足了请求，就不需要通过总线把访问请求送往主存(内存)，这毕竟是慢的。高速缓存的命中通常需要两个时钟周期。**高速缓存未命中**，就必须访问内存，这需要付出大量的时间代价。由于高速缓存价格昂贵，所以其大小有限，有些机器具有两级甚至三级高速缓存，每一级高速缓存比前一级慢但是容量大。

缓存在计算机科学的许多领域中起着重要的作用，并不仅仅只是RAM（随机存取存储器）的缓存行。只要存在大量的资源可以划分为小的部分，那么这些资源中的某些部分肯定会比其他部分更频发地得到使用，此时用缓存可以带来性能上的提升。一个典型的例子就是操作系统一直在使用缓存，比如，多数操作系统在内存中保留频繁使用的文件（的一部分），以避免从磁盘中重复地调用这些文件，类似的/root/a/b/c/d/e/f/a.txt的长路径名转换成该文件所在的磁盘地址的结果然后放入缓存，可以避免重复寻找地址，还有一个web页面的url地址转换为网络地址(IP)地址后，这个转换结果也可以缓存起来供将来使用。

缓存是一个好方法，在现代cpu中设计了两个缓存，再看3.1.5中的两种cpu设计图。第一级缓存称为L1总是在CPU中，通常用来将已经解码的指令调入cpu的执行引擎，对那些频繁使用的数据字，多数芯片还会安装第二L1缓存 … 另外往往设计有二级缓存L2，用来存放近来经常使用的内存字。L1与L2的差别在于对cpu对L1的访问无时间延迟，而对L2的访问则有1-2个时钟周期（即1-2ns）的延迟。

#### 内存

再往下一层是主存，此乃存储器系统的主力，主存通常称为**随机访问存储(可读可写)`RAM`**，就是我们通常所说的内存，容量一直在不断攀升，所有不能再高速缓存中找到的，都会到主存中找，**主存是易失性存储，断电后数据全部消失**。

除了主存RAM之外，许多计算机已经在使用少量的**非易失性随机访问存储如`ROM`(Read Only Memory)**，在电源切断之后，非易失性存储的内容并不会丢失，ROM只读存储器在工厂中就被编程完毕，然后再也不能修改。ROM速度快且便宜，在有些计算机中，用于启动计算机的引导加载模块(BIOS)就存放在ROM中，另外一些I/O卡也采用ROM处理底层设备的控制。 

**`EEPROM`（Electrically Erasable PROM，电可擦除可编程ROM）和`闪存`（flash memory）也是非易失性的**，但是与ROM相反，他们可以擦除和重写。不过重写时花费的时间比写入RAM要多。在便携式电子设备中中，闪存通常作为存储媒介。闪存是数码相机中的胶卷，是便携式音译播放器的磁盘，还应用于固态硬盘。闪存在速度上介于RAM和磁盘之间，但与磁盘不同的是，闪存擦除的次数过多，就被磨损了。



还有一类存储器就是**`CMOS`，它是易失性的**，许多计算机利用CMOS存储器来**保持当前时间和日期**。CMOS存储器和递增时间的电路由一小块**电池驱动**，所以，即使计算机没有加电，时间也仍然可以正确地更新，除此之外**CMOS还可以保存配置的参数，比如，哪一个是启动磁盘等**，之所以采用CMOS是因为它耗电非常少，一块工厂原装电池往往能使用若干年，但是当电池失效时，相关的配置和时间等都将丢失

#### 硬盘（磁盘/机械硬盘）

> ![3](https://i.loli.net/2020/05/03/17kJ8TzIfXl4rix.png)
>
> <img src="https://i.loli.net/2020/05/03/cNI7GgKnPJVzvMS.png" alt="4" style="zoom:80%;" />

磁盘低速的原因是因为它一种机械装置，在磁盘中有一个或多个金属盘片，它们以5400，7200或10800rpm（RPM =revolutions per minute 每分钟多少转 ）的速度旋转。从边缘开始有一个机械臂悬在盘面上，这类似于老式黑胶唱片机上的拾音臂。信息卸载磁盘上的一些列的同心圆上，是一连串的2进制位（称为bit位），为了统计方法，8个bit称为一个字节Bytes，1024Bytes=1kB，1024kB=1MB，1024MB=1GB，1024GB=1TB，1024TB = 1PB所以我们平时所说的磁盘容量最终指的就是磁盘能写多少个2进制位。

每个磁头可以读取一段换新区域，称为**`磁道`**。

把一个机械手臂位置上所有的磁道合起来，组成一个**`柱面`**。

每个磁道划成若干**`扇区`**，站在硬盘的角度，一次性读写数据的最小单位为扇区，一个扇区通常为512Bytes。

操作系统一次性读写的单位是一个Block块，默认是8个扇区，也就是4096Bytes

#### 硬盘的IO延迟问题

**数据都存放于一段一段的扇区，即磁道这个圆圈的一小段圆圈，从磁盘读取一段数据需要经历寻道时间和延迟时间**

**平均寻道时间：**

机械手臂从一个柱面随机移动到相邻的柱面的时间称为寻道时间，找到了磁道就意味着找到了数据所在的那个圈圈，但是还不知道数据具体这个圆圈的具体位置。受限于物理工艺水平。

**平均延迟时间：**

机械臂到达正确的磁道之后还必须等待旋转到数据所在的扇区下，这段时间称为延迟时间。受限于硬盘的转速！

IO延迟 = 平均寻道时间+平均延期时间。

> **`优化程序运行效率的一个核心法则：能从内存取数据，就不要从硬盘取数据`**

#### 虚拟内存

许多计算机支持虚拟内存机制，该机制使计算机可以运行大于物理内存的程序，方法是将正在使用的程序放入内存执行，而暂时不需要执行的程序放到磁盘的某块地方，这块地方成为虚拟内存，在linux中称为swap，这种机制的核心在于快速地映射内存地址，由cpu中的一个部件负责，成为存储器管理单元(Memory Management Unit， MMU)

> 从一个程序切换到另外一个程序，称为上下文切换(context switch),缓存和MMU的出现提升了系统的性能，尤其是上下文切换。

> PS：磁带：
>
> 在价钱相同的情况下比硬盘拥有更高的存储容量，虽然速度低于磁盘，但是因其大容量，在地震水灾火灾时可移动性强等特性，常被用来做备份。（常见于大型数据库系统中）

### IO设备

**IO设备 = 设备的控制器+设备本身**

cpu和存储器并不是操作系统唯一需要管理的资源，I/O设备也是非常重要的一环。

见1.1的图，**I/O设备一般包括两个部分：设备控制器和设备本身**。

控制器：是查找主板上的一块芯片或一组芯片（硬盘，网卡，声卡等都需要插到一个口上，这个口连的便是控制器），控制器负责控制连接的设备，它从操作系统接收命令，比如读硬盘数据，然后就对硬盘设备发起读请求来读出内容。

控制器的功能：通常情况下对设备的控制是非常复杂和具体的，控制器的任务就是为操作系统屏蔽这些复杂而具体的工作，提供给操作系统一个简单而清晰的接口

设备本身：有相对简单的接口且标准的，这样大家都可以为其编写驱动程序了。要想调用设备，必须根据该接口编写复杂而具体的程序，于是有了控制器提供设备驱动接口给操作系统。必须把设备驱动程序安装到操作系统中。

### 总线

在第1节的结构在小型计算机中沿用了多年，并也用在早期的IBM PC中。但是随着处理器和存储器速度越来越快，单总线很难处理总线的交通流量了，于是出现了下图的多总线模式，他们处理I/O设备及cpu到存储器的速度都更快。

北桥即PCI桥：连接高速设备

南桥即ISA桥：连接慢速设备

> ![](https://images2015.cnblogs.com/blog/1036857/201701/1036857-20170118183358656-1969770652.png)

主板图解：

![](https://images2018.cnblogs.com/blog/1036857/201803/1036857-20180314164300354-1096940375.jpg)

### 操作系统启动流程

在计算机的主板上有一个基本的输入输出程序（Basic  Input Output System)

BIOS就相当于一个小的操作系统，它有底层的I/O软件，包括读键盘，写屏幕，进行磁盘I/O,该程序存放于一非易失性存储ROM中。

**启动流程：**

1.计算机加电

2.BIOS开始运行，检测硬件：cpu、内存、硬盘等

3.BIOS读取CMOS存储器中的参数，选择启动设备

4.从启动设备上读取第一个扇区的内容（MBR主引导记录512字节，前446为引导信息，后64为分区信息，最后两个为标志位）

5.根据分区信息读入bootloader启动装载模块，启动操作系统

6.然后操作系统询问BIOS，以获得配置信息。对于每种设备，系统会检查其设备驱动程序是否存在，如果没有，系统则会要求用户安装设备驱动程序。一旦有了全部的设备驱动程序，操作系统就将它们调入内核。然后初始有关的表格（如进程表），传进需要的进程，并在每个终端上启动登录程序或GUI

> 补充：**应用程序的启动流程**
>
> 1. 双击exe快捷方式，该快捷方式指向一个绝对路径
> 2. 操作系统会根据路径找到exe程序在硬盘中的位置，控制其代码从硬盘加载到内存
> 3. 然后CPU从内存中读取刚刚读入内存的程序代码执行，应用程序完成启动

## 参考：

[1]	https://www.cnblogs.com/linhaifeng/p/6523843.html#4462371

[2]	https://zhuanlan.zhihu.com/p/108350791