计算机是严谨的,输入与输出有着严格的end to end的关系,我们要处理的中央处理器(CPU),也是这样的装置。

处理器是一个机械地进行数据处理的装置, 它要做何种处理, 就应该是受到某种方式的控制, 而不存在可以自己思考的智能。这样的处理器的媒介,就是指令。我们可以用加法字段对两个数据相加,和我们在计算器中的控制码是非常的类似的。

要”用加法指令来控制处理器对两个数据进行相加”, 说明一条指令需要给出两方面的信息: 一方面, 计算机需要处理的数据有很多, 因此指令中需要指定需要处理哪些数据, 这称为指令的”操作数”(operand)字段; 另一方面, 计算机处理数据的方式也有很多种, 因此指令中也需要指定用何种方式处理数据, 这称为指令的”操作码”(opcode)字段.

我们看到,在计算中的很多结果,需要保存起来供后续使用,这种东西就叫做寄存器。由于这样的寄存器用于处理一般数据,一次也称为通用寄存器(GPR)。相对地,有一些寄存器地功能并不是用于一般处理,便不叫作GPR

存储程序

程序的本质就是一段指令序列

那就有一个问题,计算机为什么会比计算器强太多。答案在于计算机的工作机制: 它可以让程序来自动控制计算机的执行.具体地, 我们可以先把一段指令序列放在存储器(如现代计算机的内存)中, 让计算机从内存中取出指令来执行; 重要的是, 当计算机执行完一条指令之后, 就继续执行下一条指令. 为了能让计算机知道下一条指令在哪里, 还需要有一个用于指示当前执行到哪条指令的部件, 这个部件称为“程序计数器”(Program Counter, PC).

从此以后, 计算机只需要做一件事情:

1
2
3
4
重复以下步骤:
从PC指示的存储器位置取出指令
执行指令
更新PC

如果是PC存储了当前的指令地位置,那PC也应该是一个寄存器,所以有一些新的玩法。比如说bner0指令。它是Branch if Not Equal r0的缩写, 如果执行这条指令的时候R[rs2]R[0]不相等, 则将PC寄存器更新为addr,类似于我们看到的特殊函数“jump”。

计算10以内的奇数之和

尝试用上述指令编写一个程序, 求出10以内的奇数之和, 即计算1+3+5+7+9. 编写后, 尝试列出处理器状态的变化过程, 以此来检查你编写的程序是否正确.
我们计算得到最后的结果是25,可以用一个大于四位的一个寄存器。

我们需要

  • 一个寄存器寄存9,bner0进行终止程序
  • 一个寄存器寄存被加数,即为1,3,5,7,9;
  • 我们要对被加数的寄存器进行迭代,所以我们需要一个加数,寄存器寄存2

所以其实现可以位:

1
2
3
4
5
6
7
8
1: li r0 9
2: li r1 0
3: li r2 1
4: li r3 2
5: add r1 r1 r2
6: add r2 r2 r3
7: benr0 r2 5
8: nop

指令集架构的状态机模型

GPR, PC, 存储器, 指令及其执行过程, 在计算机领域中属于指令集架构Instruction Set Architecture, 缩写为ISA, 也简称指令集)的范畴. 你可能听说过x86, ARM, RISC-V等概念, 它们其实都是ISA.

我们先来一个对我们理解计算机系统非常重要的数学模型: 状态机.

image.png
我们在状态机的视角去理解ISA

  • 状态:PC GPR和内存
  • 激励事件:指令
  • 状态转移规则:由指令决定
  • 初始状态

C语言

C是一门高级编程语言,C是高级编程语言中,和计算机的实际的处理过程非常接近的一种,我们几乎能从代码本身中看出计算机时如何执行的。

c语言中的注释和do-while循环:

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

/* 1 */ int main() {
/* 2 */ int sum = 0;
/* 3 */ int i = 1;
/* 4 */ do {
/* 5 */ sum = sum + i;
/* 6 */ i = i + 1;
/* 7 */ } while (i <= 10);
/* 8 */ printf("sum = %d\n", sum);
/* 9 */ return 0;
/* 10*/ }

数字电路的状态机模型

  • 状态集合:时序逻辑电路的所有原件及其储存的,基本信息
  • 激励事件集合:由其输入决定
  • 状态转移规则:由元件具体决定
  • 初始状态

C程序的计算机执行

编译,就是把C的指令翻译为计算机的指令序列

CPU设计 = 根据ISA设计数字电路

image.png

就是用数字电路的状态机实现ISA的状态机。

下面摘取“一生一芯”中的一句话,简述一下他想要说明的:

机器永远是对的. 计算机系统的行为是按照官方手册的描述精确发生的, 系统的每一次状态转移都有手册依据. 换句话说, 如果你不理解计算机系统的行为, 很大概率是因为你不了解相关手册中的某些关键细节.

你在刚学习”一生一芯”的时候可能会感受到未知的事物像潮水一般袭来. 但只有树立正确的观念, 才有助于解决问题. 有的初学者会提出”是不是操作系统有问题”, “是不是编译器有bug”等疑问, 这些不专业的想法并不能帮助你真正解决问题, 不能帮助你获得真正的成长.