用计算机指令编写的程序叫做,计算机基础第五章:指令和程序(Instruction&Programs)...

本文介绍了CPU的工作原理,通过一个简化模型展示了如何用基本指令执行程序。文中详细解释了加载、存储、加法、减法、跳转等指令,并通过一个示例程序阐述了如何利用这些指令实现特定计算任务。此外,讨论了现代CPU如何通过增加指令位数和采用可变指令长度来扩展指令集,以适应更复杂的计算需求。
摘要由CSDN通过智能技术生成

指令和程序(Instruction&Programs)

一.前言

前一章我们把ALU,控制单元,RAM,时钟结合在一起,做了一个简单的“中央处理单元”——CPU

7b06c614ffd37234bb188ef01cd94a51.png

上次我们还编写了一个简单的程序,这一章我们继续进一步抽象,来编写一个更复杂的程序。CPU之所以强大,就是因为它是可编程的,我们可以编写不同的指令,来执行定制化的业务。

二.更多的“计算机指令”

我们来用更多的命令来制作一个更加复杂的程序,回顾之前的命令程序

我们把命令前四位作为指令“操作码”,后四位RAM地址或者寄存器地址,第一个命令是意思是:把后 4 位指定的内存地址的值,放入寄存器 A,后 4 位是 1110,十进制的 14,我们前面的程序有4个指令,RAM还有数字 3和 14,

4a6b81757bec6a1f957928526258d93c.png

我们来换一种思路,来把 0010 1110 命令进行一种新的抽象,把难懂的二进制变成更容易理解的代码和十进制数字的组合,比如我们把0010 1110看成 "LOAD_A 14" 指令,以此类推其它几个指令分别为:“LOAD B 15”,“ADD B A”,“STORE A”,值得注意的是“ADD B A”命令B和A的顺序都不能改变,因为结果会存在第二个寄存器,如图所示:

7e3f46515e728272119abd7b916040f0.png

我们再通过流程图片将上一章我们做的程序简单过一遍,只不过这次用我们取代了二进制代码,选用了更好理解的字母和十进制数字组成的代码,流程图如下:

3b8ca27d09926f88735bb2ef6868ba14.png

c9da0ef57ba611cbf74e919363efe16c.png

56153af4a9a48dc100f053ee2bdc1d3d.png

cadb669206a1e0aa5f921171a9c1e2ad.png

一切OK,下面我们来在原有的命令上增加一些命令吧

93183d2eb5073ab3aa4322b61767dd6d.png

1.SUB 是减法,和 ADD 一样也要 2 个寄存器来操作;

2.还有 JUMP(跳转)让程序跳转到新位置,如果想改变指令顺序,或跳过一些指令,这个很实用;

3.还有一个特别版的 JUMP 叫 JUMP_NEGATIVE,它只在 ALU 的 "负数标志" 为真时,才会进行 JUMP,如图回顾ALU的抽象结构:

227e16aae24fdc3c1c88efd25277660f.png

如果如果NEGAIVE为假,JUMP_NEGAIVE就不会执行,程序进行下一步;

4.最后计算机还需要知道什么时候停下来,所有还要HALT指令,我们之前的程序最后一步应该也要在最后一步加上HALT,才能正确工作,否则跑完 STORE_A 13 之后,CPU 会不停运行下去,因为 0 不是操作码,所以电脑会崩掉!还有一点要提到HALT,指令和数据都是存在同一个内存里的,所有HALT还可以区分指令和数据。

三.一个更复杂的程序

一切准备就绪后,我们写一个把现前新学习的命令融入,写一个更复杂一点程序

我们逐步梳理这个程序,不要嫌麻烦,理解下面的内容对于以后理解高级编程语言或者汇编语言编程都有很大的作用:

1.就像之前,程序先把内存值放入寄存器 A 和 B

95621cebb922c96317cd1845c0579944.png

2.寄存器 A 是 11,寄存器 B 是 5

c627fbeb588412cf24cf17e39a2d06fa.png

3.SUB B A,用 A 减 B,11-5=6,把 6 存入寄存器 A

3b03f4e1e9cc772595a5df2ed2663975.png

4.然后JUMP NEGATIVE 出场,上一次 ALU 运算的结果是 6,所有“负数标志”为False,因此处理器不会执行JUMP操作,继续执行下一条指令

ecc856a0051f5d99d22831dd8ec404c4.png

5.下一条指令是JUMP2,JUMP 2 没有条件,直接执行!

4bd874c8f296bd613e3401c7f4c0d2ca.png

6.又回到地址2对应的命令“SUB B A”,寄存器 A-B,6-5=1,结果变成1

bb288d1085be1e2ceb47cee46ff91ae4.png

7.继续下一条命令,又是 JUMP NEGATIVE,因为 1 还是正数,因此 JUMP NEGATIVE还是 不会执行

b866b9ce6a05b0ab2a7e430b3a152d15.png

8.继续来到下一条指令,JUMP 2,这次SUB指令结果就不一样了,1-5=-4,结果为负数,ALU的 "负数标志" 是真

4469f85cf49ecff1ce278696fc78649f.png

896e55a4c50b6006b8927222e09a68bf.png

9.现在下一条指令JUMP NEGATIVE 5, CPU 的执行跳到内存地址 5,跳出了循环!

f1da049cd5cf01711906f5ef4e8859a9.png

10.现在的指令是 ADD B A,-4+5=1,1 存入寄存器 A

ce8e98700ae2c26b8adac1916c2f2d93.png

11.下一条指令 STORE_A 13,把 A 的值存入内存地址 13

f8693f4df085ee6bce29c77187405c1f.png

12.最后碰到 HALT 指令,程序停下来,结束

b2324f078f14ebf464f7c933096c70bd.png

回顾整个过程是不是发现程序两个数累减求余数,早期计算机的乘除法就是通过累加累减实现的。

虽然程序只有 七个指令,但 CPU 执行了十多个指令,因为在内部循环了两次,而且这个程序会根据我们的输入不同从而执行指令的次数也是灵活多变的,这就是软件的强大之处,最早硬件ALU不能实现除法,最早的ALU就是程序进行处理的。

我们这里假设的 CPU 很基础,所有指令都是 8 位,操作码只占了前面 4 位,即便用尽 4 位,也只能代表 16 个指令,所以我们只能操作 16 个地址,这在如今计算机肯定是远远不够用的,我们甚至不能用 JUMP 17,因为 4 位二进制无法表示数字 17,因此,真正的现代 CPU 用两种策略来改进这一问题,最简单粗暴的方法是用更多位来代表指令,比如 32 位或 64 位,第二个策略是 “可变指令长度”,也就是不再去限制指令长度,指令后面直接跟“立即值”,举个例子,比如某个 CPU 用 8 位长度的操作码,如果看到 HALT 指令,HALT 不需要额外数据,那么会马上执行,但是如果看到 JUMP,它就得知道位置值,这个值就跟在 JUMP 的后面,叫做“立即值”,这样设计,指令可以是任意长度,但会让读取阶段复杂一点点。

四.真实的CPU

其实我们前面举例的CPU和指令其实都是假设和抽象的,只是为了让我们更简单的学习核心原理知识。所以我们来看一个真实的CPU长啥样。1971年,英特尔发布了 4004 处理器,这是第一次把 CPU 做成一个芯片,给后来的英特尔处理打下了基础

298951e2b9b9c94519a1cc2f270b0baf.png

它一共支持46个命令

5c09c426ecc3542c888a0e8d394fb963.png

它用了很多我们说过的指令,比如 JUMP ADD SUB LOAD,它也用 8 位的"立即值"来执行 JUMP, 以表示更多内存地址

随着技术的不断发展,现代 CPU, 比如英特尔酷睿 i7, 有上千个指令和指令变种,指令越来越多,是因为给 CPU 设计了越来越多功能越来越多,我们后面会介绍计算机高级CPU设计。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值