
解释程序:逐句翻译、生成中间代码、不生成目标代码(边翻译边执行)
编译程序:生成中间代码、生成目标代码
解释和编译统称为翻译
MAR存放欲访问的存储单元地址、PC存放下一条指令的地址、MDR存放从存储单元取来的数据、IR存放当前执行的指令
CPU存取速度:寄存器 > Cache > 内存
寄存器在CPU内部速度最快
Cache采用高速的SRAM制作,而内存采用DRAM制作
CPU由运算器和控制器两个部件组成,而运算器和控制器中都含有寄存器

相联存储器既可以按地址寻址,又可以按内容寻址,为了与传统存储器区分,又称为按内容寻址的存储器
在计算机多层次结构中,上下层是可以分割的,且上层是下层的功能实现,此外上层在下层的基础上实现了更加丰富的功能,仅有下层而没有上层也是可以的
机器字长:CPU进行一次整数运算所能处理的二进制数据的位数(通常和ALU直接相关),也叫计算机的位数,等于寄存器的位数,
存储字长:一个存储单元中二进制代码位数(通常和MDR位数相同)
指令字长:一条指令的总长度(可能会变)
数据字长:数据总线一次能并行传送信息的位数
用户可见的寄存器(也就是用户可以设置值):通用寄存器组、程序状态字寄存器PSW、程序计数器PC
用户不可见的寄存器:MAR、MDR、IR、暂存寄存器
如果计算机 按字节编址,则 每个存储单元大小为1字节,即1B,也就是8个二进制位。
如果计算机 按字编址,则 每个存储单元大小为一个字,字的长度取决于计算机字长是多少位,若题目条件说字长是16位,则一个字就是16个二进制位。也有的计算机字长是32位、64位等等。
小端方式:最低有效地址存放在更低地址(低存低)
边界对齐存储:总空间是最大类型所占空间的整数倍。
任意进制 <=> 十进制:
任意进制 => 十进制:乘对应基数,小数点左边从基数的0次方开始
二
进
制
:
101.1
−
>
1
×
2
2
+
0
×
2
1
+
1
×
2
0
+
1
×
2
−
1
=
5.5
八
进
制
:
5.4
−
>
5
×
8
0
+
4
×
8
−
1
=
5.5
十
进
制
:
5.5
−
>
5
×
1
0
0
+
5
×
1
0
−
1
=
5.5
十
六
进
制
:
5.8
−
>
5
×
1
6
0
+
8
×
1
6
−
1
=
5.5
二进制:101.1 \quad -> 1×2^2+0×2^1+1×2^0+1×2^{-1} = 5.5 \\ 八进制:5.4 \quad -> 5×8^0+4×8^{-1} = 5.5 \\ 十进制: 5.5 \quad -> 5×10^0+5×10^{-1} = 5.5 \\ 十六进制: 5.8 \quad -> 5×16^0+8×16^{-1} = 5.5
二进制:101.1−>1×22+0×21+1×20+1×2−1=5.5八进制:5.4−>5×80+4×8−1=5.5十进制:5.5−>5×100+5×10−1=5.5十六进制:5.8−>5×160+8×16−1=5.5
十进制 => 任意进制:
二进制 <=> 八进制
二进制 <=>十六进制

正数:
负数:(如上图)
负数的反码:将原码的数值位全部取反
负数的补码:反码末位+1
移码:在补码的基础上将符号位取反
负数将反码转换成原码和原码转换成反码的 方式相同,都是把数值位(尾数)取反
负数将补码转换成原码和原码转换成补码的方式相同,都是把数值位(尾数)取反,然后末位+1
由[x]补快速求[-x]补的方法:符号位、数值位全部取反,末位+1
原码和反码的真值0有两种表示,补码和移码的真值0只有一种表示。若机器字长为n+1位,则:
| 整数表示范围 | 小数表示范围 | |
|---|---|---|
| 原码和反码 | -(2n-1) ≤ x ≤ 2n-1 | -(1-2-n) ≤ x ≤ 1-2-n |
| 补码 | -2n ≤ x ≤ 2n-1 | -1 ≤ x ≤ 1-2-n |
| 移码 | -2n ≤ x ≤ 2n-1 | 移码全0真值最小,移码全1真值最大 |
补码正数比原码多表示一个 -2n,补码小数比原码多表示一个 -1
原码的算数移位:符号位保持不变,仅对数值位进行移位。
算数左移:低位补0,高位舍弃。
算数右移:高位补0,低位舍弃。
只对数值位移动,左移相当于×2,右移相当于÷2
反码的算数移位:
补码的算数移位:
正数补码的算数移位和原码的算数移位相同
负数补码中,最右边的1及其右边同原码的算数移位,最右边的1的左边同反码的算数移位:
不区分正数的另一种记忆规律:🔥
- 补码的算数右移:符号位不动,数值位右移,符号位是啥就补啥
- 补码的算数左移:符号位不动,数值位左移,通通补0
可以把逻辑移位看作是对"无符号数"的算数移位
不带进位位的循环移位:无论左移还是右移,都会将移出的数补到缺位的位置
带进位位的循环移位:
仅当两个符号相同的数相加或两个符号相异的数相减才可能产生溢出,只需学习补码的溢出判断:
设A的符号为 AS,B的符号为BS,运算结果的符号为SS,则溢出逻辑表达式为:
V
=
A
S
B
S
S
s
‾
+
A
S
‾
B
S
‾
S
S
若
V
=
0
,
表
示
无
溢
出
若
V
=
1
,
表
示
有
溢
出
V = A_SB_S \overline {S_s}+ \overline {A_S} \overline {B_S} S_S \\ 若 V = 0,表示无溢出 \\ 若 V = 1,表示有溢出
V=ASBSSs+ASBSSS若V=0,表示无溢出若V=1,表示有溢出
写在一起执行与运算(也就是且),加号表示或运算,上方画横线表示非运算。
方法二:采用一位符号位,根据数据位进位情况判断溢出
方法三:采用双符号位:正数符号为00,负数符号为11🔥
定点整数的符号扩展:在原符号位和数值位中间添加新位,正数都添0,负数原码添0,反码、补码添1
定点小数的符号扩展:在原符号位和数值位后面添加新位,正数都添0,负数原码、补码添0,反码添1
找到最右边的1,补码这个1的左边的数值部分和反码一致,1的右边数值部分和原码保持一致


写出[|x|]补 、[|-x|]补 、[|y|]补
按如上图那样写,其中第二列需写 [|y|]补全部+辅助位 ,然后在辅助位前面划条竖线,用辅助位-运算位(竖线后减竖线前)
每轮加法之后,ACC、MQ的内容统一算数右移(补码的算数右移)
|y|补的数值部分占n位,则(加法、移位)看成一个操作执行n次,但是补码乘法运算最后要多加一轮加法(也是看竖线后-竖线前的数字来决定加什么)
将ACC的全部+MQ的前n个位拼接,得到的即为[xy]补 = 11.01110001,前面的11即为符号位负,则xy=-0.01110001(真值)
| 原码一位乘法 | 补码一位乘法 | |
|---|---|---|
| 加法、移位次数 | n轮加法、n轮移位 | n+1轮加法、n轮移位 |
| 移位 | 逻辑右移 | 算数右移 |
| 符号位是否参与 | 符号位不参与运算 | 符号位参与运算 |
| 加什么 | 根据MQ的最低位(即运算位)来确定加什么 | 根据MQ的辅助位、最低位来确定加什么 |


总结:
恢复余数法和加减交替法:

写出[x]补 、[y]补 、[-y]补 注意写的并不是绝对值的补码
按如上图那样写,根据 x 和 y 是同号还是异号来判断:
根据第二步得到的新余数来判断商
最后一步得到的新余数和y不管同号还是异号,我们都恒让商的末位置为1
则[x/y]补 = 商 = 1.0101
除法运算总结:
| 除法类型 | 符号位是否参与运算 | 加减次数 | 移位 | 商、加减原则 | 说明 |
|---|---|---|---|---|---|
| 原码加减交替法 | 否 | n+1或者n+2 | 逻辑左移n次 | 根据余数的正负 | 若最终余数为负,需恢复余数 |
| 补码加减交替法 | 是 | n+1 | 逻辑左移n次 | 根据余数和除数是否同号 | 商末尾恒置1 |
浮点数由阶码和尾数两部分构成:+3.026×1011
+11+3.026 前三位表示10的次方,后面5位表示尾数。
+11我们称为阶码,阶码由阶符和数值部分组成,阶码为正的话表示我们要将小数点后移,如果阶符为负表示我们要将小数点前移,阶码的数值部分表示小数点移动多少位+3.026表示尾数,尾数的正负号表示数值的正负性,后面的数字称为尾数的数值部分,尾数越短,科学计数法表示的数值精度就越低浮点数真值的确定:
N
=
r
E
×
M
阶
码
的
真
值
是
E
,
尾
数
的
真
值
是
M
,
r
表
示
几
进
制
表
示
的
阶
码
,
二
进
制
表
示
的
阶
码
r
=
2
N = r^E ×M \quad 阶码的真值是E,尾数的真值是M,r表示几进制表示的阶码,二进制表示的阶码r=2
N=rE×M阶码的真值是E,尾数的真值是M,r表示几进制表示的阶码,二进制表示的阶码r=2
规范:小数点必须在第一位有效值的后面,尾数的最高位是有效值
左归:尾数算数左移一位,阶码减1
右归:尾数算数右移一位,阶码加1
用原码表示尾数最高数值位是1即可
用补码表示尾数的符号位和最高数值位(即符号位的后一位)一定相反


IEEE754标准中阶码用移码表示,尾数用原码表示。
MDR位数 = 存储字长(数据的宽度) = 数据线的宽度, MAR位数 = 存储字数,总容量 = 存储字长 × 存储字数
存储周期 = 存取时间+恢复时间
数据传输率(主存宽带) = 存储字长(数据的宽度)/存储周期

一个个存储元构成存储单元(存储字),一个个存储单元构成存储体(存储矩阵) ,每一个存储元可以存储一位二进制0或1
字选线(译码器连接的地址线)的条数 = 存储单元个数 = 2MAR地址位数 ,数据线的条数 = MDR的位数,片选信1根,读写控制线1根或两根,地址线+数据线+片选线1+读写控制线1/2 = 金属引脚数
8×8位的存储芯片:第一个8表示存储单元的数量,第二个8表示存储字长随机存取存储器RAM:
只读存取存储器ROM:
🔥RAM和ROM都可以随机存取:存取时间与存储单元的物理位置无关
只读存储器ROM的分类:
动态DRAM用于主存,静态SRAM用于Cache
| 类型特点 | SRAM(静态RAM) | DRAM(动态RAM) |
|---|---|---|
| 存储信息 | 触发器 | 电容 |
| 破坏性读出 | 非破坏性读出 | 破坏性读出 |
| 读出后需要重写(再生) | 读出后不需要重写 | 读出后需要重写 |
| 运行速度 | 快 | 慢 |
| 集成度 | 低 | 高 |
| 发热量 | 大 | 小 |
| 存储成本 | 高 | 低 |
| 易失/非易失存储器 | 易失存储器(断电后信息消失) | 易失存储器(断电后信息消失) |
| 刷新(给电容充电) | 不需要刷新 | 需要刷新 |
| 送行列地址 | 同时送行列地址 | 分两次送行列地址 |
| 用途 | 常用作高速缓存Cache | 常用作主存 |
在访存期间不允许刷新DRAM刷新注意的问题:
假设DRAM内部有128行×128列的存储单元,并且每个读写周期是0.5us,那么电容可以坚持的最长的时间是 2ms/0.5us=4000个读写周期,读写周期也称为存取周期
思路一:每次读写完都刷新一行【分散刷新】
思路二:2ms内集中安排时间全部刷新【集中刷新】
思路三:2ms内每行刷新1次即可【异步刷新】
分两次送行列地址会导致地址线、地址线引脚减半
若某个存储单元所存储的信息被读出时原存储信息被破坏,则称为破坏性读出,若读出时被读单元原存储信息不被破坏,则称为非破坏性突出
具有破坏性读出性能的存储器,每次读出操作后,必须紧接一个再生的操作,以便恢复被破坏的信息
需要刷新的只有DRAM,其他的都不需要(ROM等等)🔥
存取时间 == 总线传输周期 (第六章做题要用到)
位扩展可以使存储器的字长变得更长,从而更好发挥数据总线的数据传输能力。
字扩展可以增加存储器的存储字数,可以更好利用CPU的寻址能力。
我们把8片8K×1位的存储芯片通过位扩展扩展成1个8K×8位的存储器,总容量为8KB
字扩展有两种方法:
| 线选法 | 译码片选法 |
|---|---|
| n条地址线,产生n条片选信号 | n条地址线,产生2n条片选信号 |
| 电路简单 | 电路复杂 |
| 地址空间不连续 | 地址空间可连续 |
线选法:将n条多余的地址线将它们作为n个片选信号,电路简单,地址空间不连续
译码器片选法:将n条多余的地址线将它们作为2n个片选信号,电路复杂,地址空间连续
2-4译码器,输入2个地址信号,会输出4个片选信号
3-8译码器,输入3个地址信号,会输出8个片选信号
单体多字系统的特点是存储器中只有一个存储体,每个存储单元存储m个字,总线宽度也为m个字,一次并行读出m个字,地址必须顺序排列并处于同一存储单元
高位交叉编址:高位地址表示体号,低位地址为体内地址。访问一个连续主存块时总是先在一个模块内访问,等到该模块访问完才转到下一个模块访问,CPU总是按顺序访问存储模块,各模块不能并行访问,因而不能提高存储器的吞吐率。
低位交叉编址🔥:低位地址为体号,高位地址为体内地址。采用这种编址方式的存储器称为交叉存储器,采用低位交叉编址后,可在不改变每个模块存取周期的前提下,采用流水线的方式并行存取,提高存储器的带宽

存取周期为T,存取时间(总线传输周期)为r。为了使得流水线不间断,应保证存储体数 m ≥ T/r 。
高位交叉编址:连续取n个存储字,耗时nT
低位交叉编址:连续取n个存储字,耗时T+(n-1)r
多体并行存储器:
单体多字存储器适合用来读取指令和数据在主存内是连续存放的。

哪个硬盘的哪个盘面的哪个磁道的哪个扇区


当CPU访问了主存的某一个存储块之后,一定会把这个主存块调入cache(复制一份)。
只要知道访问Cache所需要的时间和访问主存所需要的时间以及Cache的命中率,我们就可以算出 Cache-主存 系统的平均访问时间:
t
=
H
t
c
+
(
1
−
H
)
(
t
c
+
t
m
)
平
均
访
问
时
间
=
C
a
c
h
e
命
中
率
×
访
问
一
次
C
a
c
h
e
时
间
+
未
命
中
率
×
(
访
问
一
次
主
存
时
间
+
访
问
一
次
C
a
c
h
e
时
间
)
t
c
<
t
<
t
m
t = Ht_c+(1-H)(t_c+t_m) \\ 平均访问时间 = Cache命中率×访问一次Cache时间+未命中率×(访问一次主存时间+访问一次Cache时间) \\ t_c < t
上述公式的含义是CPU是先去Cache里面找,无论找得到找不到都需要花tc的时间,若没有命中,则CPU会去主存里面找数据,共花费tc+tm的时间,这种情况发生的概率为1-H。
当CPU同时去Cache和主存里面找数据,当经过tc时间,在Cache里面命中,则立即停止在内存中的查找,所以在命中的情况下CPU的访问时间同样只需要tc的时间,这种情况发生的概率为H。若在Cache里面没有命中,啧经过tmCPU就可以在内存当中找到数据,而这种情况发生的概率为1-H。
t
=
H
t
c
+
(
1
−
H
)
t
m
t=Ht_c+(1-H)t_m
t=Htc+(1−H)tm


先进先出算法和近期最少使用算法都有可能发生抖动现象:频繁的换入换出现象(刚被替换的块很快又被调入)

我们之前学过机器字长和存储字长:
机器字长:CPU进行一次整数运算所能处理的二进制数据的位数(通常和ALU直接相关) 与寄存器位数有关
存储字长:一个存储单元中二进制代码位数(通常和MDR位数相同) 一个存储单元的位数
指令字长:一条指令的总长度(可能会变)
机器字长和CPU有关,一般是固定不变的,而存储字长和主存有关,一般也是固定不变的,但是指令字长是有可能发生改变的,

零地址指令:只需要操作码,不需要地址码。使用情况有以下两种:
一地址指令:需要一个地址码。使用情况有以下两种:
要进行的操作只需要单操作数,如加1、减1、取反、求补码等操作
要进行的操作需要两个操作数,其中一个地址码显式的显示,另一个操作数隐含在某个寄存器(如隐含在ACC)
二地址指令:需要一个目的操作数A1和源操作数A2
指令含义:(A1)OP(A2)->A1 ,将A1地址和A2地址的内容读出,执行OP操作后,将结果放入A1地址。【结果放入目的操作数】
完成上述指令需要访存4次:1. 取二地址指令 2. 读A1地址 3. 读A2地址 4. 将结果写入A1地址
常用于需要两个操作数的算术运算、逻辑运算相关指令
三地址指令:需要一个目的操作数A1、源操作数A2和结果操作数 A3
四地址指令:需要一个目的操作数A1、源操作数A2、结果操作数 A3 和下一条将要执行指令的地址A4
n位地址码的直接寻址范围 = 2n
指令的地址个数与指令的长度是否固定没有必然联系。例如单地址指令是固定长度的指令是错误的,地址位数固定,操作码位数可以更改
单字长指令由于每个指令字长都相同,因此单字长指令可加快取指令的速度
指令的地址码字段存放的可以是操作数(立即数)、操作数的地址、寄存器的编号
加法指令的执行周期不一定要访存:取指令去指令Cache里面去取,两个地址码均采用寄存器寻址,最后将结果写回,可以在Cache中写,这样一套下来均不用访存
指令操作所需的操作不会来自控制存储器,控制器是ROM,里面只有微指令
指令由操作码和若干个地址码组成。
定长指令字结构+可变长操作码 -> 扩展操作码指令格式:指令的总长度固定不变,但是操作码的位数可以改变的扩展操作码指令格式,不同地址数的指令使用不同长度的操作码。
设地址长度为n,上一层留出m种状态,下一层可扩展出m×2n种状态
定长操作码: 在指令字的最高位部分分配固定的若干位(定长)表示操作码。
扩展操作码(不定长操作码) :全部指令的操作码字段的位数不固定,且分散地放在指令字的不同位置上。

有效地址(真实地址):使用EA表示,指令里面的形式地址:用A表示
| 寻址方式 | 有效地址 | 访存次数(指令执行期间) |
|---|---|---|
| 隐含寻址 | 程序指定 | 0 |
| 立即寻址🔥 | A即是 操作数 | 0 |
| 直接寻址🔥 | EA=A | 1 |
| 一次间接寻址🔥 | EA=(A) | 2 |
| 寄存器寻址 | EA=Ri | 0 |
| 寄存器间接一次寻址 | EA=(Ri) | 1 |
隐含寻址:在指令中隐含着操作数的地址
立即寻址:指令的形式地址A就是我们想要的操作数,形式地址A就是操作数本身,又称为立即数,一般采用补码形式
直接寻址:指令中的形式地址A就是操作数的有效地址EA,即EA=A
直接寻址访存次数:取一地址指令访存1次,执行指令访存1次(根据形式地址A去主存读取),共2次访问
优点:简单,指令执行阶段仅访问1次主存,不需专门计算操作数的地址。
缺点:形式地址A的位数决定了该指令操作数的寻址范围。操作数的地址不易修改(若主存中的A地址修改,那么操作数的地址也要修改)
间接寻址:指令的地址字段给出的形式地址不是操作数的真正地址,而是操作数有效地址所在的存储单元的地址,也就是操作数地址的地址,即EA=(A)
取一地址指令访存1次,执行指令访存1次(根据形式地址A去主存读取),根据EA地址再进行1次访存,共3次访存
EA=(A),有效地址EA等于形式地址A所指向的主存单元的地址
优点:
缺点:
寄存器寻址:指令给出的地址码并不是指向了主存单元,而是指向了某一个寄存器的编号
取一地址指令访存1次,执行指令访存0次,共访存1次
优点:指令在执行阶段不访问主存,只访问寄存器,指令字短且执行速度快,支持向量/矩阵运算。
缺点:寄存器价格昂贵,计算机中寄存器个数有限。
寄存器间接寻址:指令给出的地址码并不是指向了主存单元,而是指向了某一个寄存器的编号,这个寄存器里面存放的内容才是我们最终要找的操作数在主存中的地址,即EA=R(i),有效地址是第i个寄存器中的内容
取一地址指令访存1次,执行指令访存1次,共访存2次
特点:与一般间接寻址相比速度更快,但指令的执行阶段需要访问主存(因为操作数在主存中)。
偏移寻址:偏移寻址包括:相对寻址、基址寻址、变址寻址。偏移寻址就是以某一个地址作为起始地址,然后偏移量为形式地址A
| 寻址方式 | 有效地址 | 访存次数(指令执行期间) |
|---|---|---|
| 相对寻址(转移指令)🔥 | EA=(PC)+A | 1 |
| 基址寻址(多道程序)🔥 | EA=(BR)+A | 1 |
| 变址寻址(循环程序、数组问题)🔥 | EA=(IX)+A | 1 |
堆栈寻址:操作数存放在堆栈中,隐含使用堆栈指针(SP)作为操作数地址。寄存器堆栈又称为硬堆栈,而从主存中划出一段区域来做堆栈是最合算且最常用的方法,这种堆栈称为软堆栈。
| 寻址方式 | 有效地址 | 访存次数(指令执行期间) |
|---|---|---|
| 堆栈寻址 | 入栈/出栈时EA的确定方式不同 | 硬堆栈不访存,软堆栈访存1次 |
注意,上面的访存次数都是指令在执行期间访存,而取指令没有算进去,取指令无论如何都是1次访存。
| 对比项目 | CISC | RISC |
|---|---|---|
| 指令系统 | 复杂,庞大 | 简单,精简 |
| 指令数目 | 一般大于200条 | 一般小于100条 |
| 指令字长 | 不固定 | 定长 |
| 可访存指令 | 不加限制 | 只有Load/Store指令 |
| 各种指令执行时间 | 相差较大 | 绝大多数在一个周期内完成 |
| 各种指令使用频度 | 相差很大 | 都比较常用 |
| 通用寄存器数量 | 较少 | 多 |
| 目标代码 | 难以用优化编译生成高效的目标代码程序 | 采用优化的编译程序,生成的代码较为高效 |
| 控制方式 | 绝大多数为微程序控制 | 绝大多数为组合逻辑(硬布线方式)控制 |
| 指令流水线 | 可以通过一定方式实现 | 必须实现 |

上图中,左边是运算器,右边是控制器,控制器组成如下:
专用数据通路方式:根据指令执行过程中的数据和地址的流动方向安排连接线路。(只要两个部件之间有数据的流动,那么我们就在这两个部件之间建立一个专门的连接线路)
CPU内部单总线方式:将所有寄存器的输入端和输出端都连接到一条公共的通路上
用户可见的寄存器:通用寄存器组、程序状态寄存器PSW、程序计数器PC
一个指令周期至少要由取指周期和执行周期两个部分组成。
如果说每一个子工作所需要消耗的时钟周期数都是相同的,那么每一个子工作所需要消耗的机器周期也是相同的,这种CPU就是定长的机器周期。取指令子工作和执行指令子工作所需要的机器周期可能是不相同的,这种CPU就是不定长的机器周期。
指令周期流程参考计组第五章2.2笔记
CPU内部单总线方式数据流动大致上分为三类:


从主存当中读取指令,PC指明了我们要读取的指令存放的地址,所以刚开始将PC的内容放到MAR中,接下来对主存进行读操作,应该读的地址存放在MAR当中,MAR是通过地址总线传送给主存的(事实上应该有一个控制信号控制MAR的内容送到主存,但是图中没画),接下来主存根据MAR所指示的地址读出相应的数据,然后把这个数据放到MDR当中(图中绿色数据线),接下来将MDR的数据放入IR当中。

当我们在执行算数或者逻辑运算时,我们的数据有可能流向ALU的,比如执行一条加法指令,其中一个数已经存放在ACC里面了,而另一个操作数会由加法指令直接指明地址,所以首先根据指令的地址码部分传送到MAR当中,要实现这个操作我们要保证IRin和MARin有效,当然也可以让MDRout和MARin有效(因为取值令结束之后MDR和IR当中都有地址信息),接下来主存进行读操作,主存根据MAR所指示的地址读出相应的数据,然后把这个数据放到MDR当中,之后先把这个数放到暂存寄存器Y当中。
微程序控制器如下图:

微程序:由微指令序列组成,微指令序列由微操作组成,每一种指令对应一个微程序。
指令是对程序执行步骤的描述,微指令是对指令执行步骤的描述
因此当CPU在执行一条机器指令的时候,其实就是要执行这条机器指令所对应的微程序
微命令与微操作一 一对应(微命令是指执行微操作发出的控制信号,可以理解为微命令=微操作),微指令中可能包含多个微命令。机器指令和微程序也是一一对应的,一种机器指令会对应一个微程序,一个微程序会由多个微指令序列组成。所以可以说机器指令是对微指令的封装。
| 对比项目 | 微程序控制器 | 硬布线控制器 |
|---|---|---|
| 工作原理 | 微操作控制信号以微程序的形式存放,在控制存储器中执行指令时读出即可 | 微操作控制信号由组合逻辑电路根据当前的指令码、状态和时序,即时产生 |
| 执行速度 | 慢 | 快 |
| 规整性 | 较规整 | 繁琐、不规整 |
| 应用场合 | CISC CPU | RISC CPU |
| 易扩充性 | 易扩充修改 | 不易扩充 |
有的微命令可以并行执行,因此一条微指令可以包含多个微命令
相容性微命令:可以并行完成的微命令。
互斥性微命令:不允许并行完成的微命令。
微指令分为三种:
水平型微指令:一条微指令能定义多个可并行的微命令。
垂直型微指令:一条微指令只能定义一个微命令,由微操作码字段规定具体功能
优点:微指令短、简单、规整,便于编写微程序
缺点:微程序长,执行速度慢,工作效率低
混合型微指令:在垂直型的基础上增加一些不太复杂的并行操作。
水平型微指令执行一条微指令可以并行的完成多个微命令,垂直型微指令执行一条指令只能完成一个微命令。
微指令的编码方式:
微指令的地址形成方式:如何确定下一条微指令的存放地址呢?
微程序设计分类:
注:参考计组第五章原笔记目录6
一条指令的执行过程可以分成多个阶段:最简单的划分方法是取指、分析、执行三个阶段(注:也可以把每条指令的执行过程分成4个或者5个阶段,分成5个阶段是比较常见的做法)。设取指、分析、执行,三个阶段的时间都相等为t,按以下几种执行方式分析n条指令单执行时间:

顺序执行方式:一条指令执行上述三个阶段后,下一条指令继续执行上述三个阶段
有n条指令,总耗时 = n×3t = 3nt
传统冯诺依曼机采用顺序执行方式,又称为串行执行方式
优点:控制简单,硬件代价小
缺点:执行指令的速度较慢,在任何时刻,处理机中只有一条指令在执行,各功能部件的利用率很低
一次重叠执行方式:第一条指令的第3个阶段和第二条指令的第2个阶段有重叠
二次重叠执行方式:

如上图,我们先画出这n条指令的时空图,第1个指令耗时为k▲t,在第1个指令完成执行后再过▲t第2个指令完成执行,之后再过▲t第3个指令执行完成,所以后续(n-1)条指令只需要再花 (n-1)▲t。
处
理
完
成
n
个
任
务
所
用
的
时
间
为
T
k
=
(
k
+
n
−
1
)
Δ
t
流
水
线
实
际
吞
吐
率
T
P
=
n
(
k
+
n
−
1
)
Δ
t
当
n
−
>
∞
,
得
到
最
大
吞
吐
率
T
P
m
a
x
=
1
Δ
t
处理完成n个任务所用的时间为T_k = (k+n-1) \Delta t \\ 流水线实际吞吐率 TP = \frac{n}{(k+n-1) \Delta t} \\ 当n->∞,得到最大吞吐率 TP_{max} = \frac{1}{\Delta t}
处理完成n个任务所用的时间为Tk=(k+n−1)Δt流水线实际吞吐率TP=(k+n−1)Δtn当n−>∞,得到最大吞吐率TPmax=Δt1
一般取▲t = 一个时钟周期,一条指令的执行被分为多个阶段,每个阶段对应一个机器周期,一个机器周期可能包含多个时钟周期,最理想的情况就是一个机器周期包含一个时钟周期。

如果不使用流水线,则完成一条指令需要k▲t,完成n条指令需要 T0=nk▲t
T
k
=
(
k
+
n
−
1
)
Δ
t
实
际
加
速
比
S
=
k
n
Δ
t
(
k
+
n
−
1
)
Δ
t
=
k
n
k
+
n
−
1
当
n
−
>
∞
,
得
到
最
大
加
速
比
S
m
a
x
=
k
T_k = (k+n-1) \Delta t \\ 实际加速比 S = \frac{kn \Delta t}{(k+n-1)\Delta t} = \frac{kn}{k+n-1} \\ 当n->∞,得到最大加速比 S{max} = k
Tk=(k+n−1)Δt实际加速比S=(k+n−1)ΔtknΔt=k+n−1kn当n−>∞,得到最大加速比Smax=k

部件功能级、处理机级和处理机间级流水
单功能流水线和多功能流水线
动态流水线和静态流水线
线性流水线和非线性流水线
超标量技术:每个时钟周期内可以并行的发多条独立指令

如上图红框,在一个时钟周期内,我们发射了三条独立指令,显然,如果我们要同时运行三条指令,这意味着我们至少要配置三个指令寄存器IR和ALU,因此
可以说使用了空分复用技术,我们增加了多个功能部件,所以支持同一时刻多个操作并行来干
超标量相当于多个流水同时进行
超流水技术:把一个时钟周期再进行分段(3段)

如上图将一个时钟周期分成了三段(图中蓝线),在一个时钟周期内的不同时间点,会发射出三条指令,这意味着在一个时钟周期内,一个功能部件可能被使用多次(3次)【可以说使用了时分复用技术】
这里其实应该说是机器周期,因为取址执行访存阶段的耗时都是定义为机器周期,但是流水线最理想的情况下,一个机器周期只包含一个时钟周期,所以这里会说时钟周期

上图只把指令的执行过程分为了4个阶段,没有写访存M阶段,在执行EX阶段有三个灰色的框。
由编译程序挖掘出指令间潜在的并行性,将多条能并行操作的指令组合成一条超长的指令,这就是为什么叫超长指令字。这种超长的指令具有多个操作码字段
总线是一组能为多个部件分时共享的公共信息传送线路。
总线按数据传输格式:分为串行总线和并行总线
按总线功能分为:片内总线、系统总线、通信总线
按时序控制方式分为:同步总线、异步总线
片内总线是连接CPU内部各个部件的,系统总线是连接计算机系统各功能部件的,通信总线是用来连接各个计算机系统的。
- 工作频率相同时,串行总线传输速度比并行总线慢
- 并行总线的工作频率无法持续提高,而串行总线可以通过不断提高工作频率来提高传输速度,最终超过并行总线
总线的传输周期(总线周期)
总线时钟周期
总线的工作频率
总线上各种操作的频率,为总线周期的倒数。若总线周期=N个时钟周期,则总线的工作频率=时钟频率/N。实际上指一秒内传送几次数据
总 线 工 作 频 率 = 1 总 线 周 期 总线工作频率 = \frac{1}{总线周期} 总线工作频率=总线周期1
总线的时钟频率
总线宽度
总线带宽
总 线 带 宽 = 总 线 工 作 频 率 × 总 线 宽 度 ( b i t / s ) = 总 线 工 作 频 率 × ( 总 线 宽 度 / 8 ) ( B / s ) = 总 线 宽 度 总 线 周 期 ( b i t / s ) = 总 线 宽 度 / 8 总 线 周 期 ( B / s ) 总线带宽=总线工作频率×总线宽度(bit/s)=总线工作频率× (总线宽度/8) (B/s) \\ = \frac{总线宽度}{总线周期}(bit/s) = \frac{总线宽度/8}{总线周期}(B/s) 总线带宽=总线工作频率×总线宽度(bit/s)=总线工作频率×(总线宽度/8)(B/s)=总线周期总线宽度(bit/s)=总线周期总线宽度/8(B/s)
注:总线带宽是指总线本身所能达到的最高传输速率。在计算实际的有效数据传输率时,要用实际传输的数据量除以耗时。
总线周期的4个阶段:
申请分配阶段:由需要使用总线的主模块提出申请,经中心仲裁机构决定,将下一传输周期的总线使用权授予某一申请者。也可将此阶段细分为传输请求和总线仲裁两个阶段
寻址阶段:获得使用权的主模块通过总线发出本次要访问的从模块的地址以及有关命令,启动参与本次传输的从模块
传输阶段:主模块和从模块进行数据交换,可单向或双向进行数据传送
结束阶段:主模块的有关信息均从系统总线上撤除,让出总线使用权
总线定时是指总线在双方交换数据的过程中需要时间上配合关系的控制,这种控制称为总线定时,它的实
质是一种协议或规则
总线定时的方案:
同步定时方式是指系统采用一个统一的时钟信号来协调发送和接收双方的传送定时关系。
若干个时钟产生相等的时间间隔,每个间隔构成一个总线周期。
在一个总线周期中,发送方和接收方可进行一次数据传送。
因为采用统一的时钟,每个部件或设备发送或接收信息都在固定的总线传送周期中,一个总线的传送周期结束,下一个总线传送周期开始。
优点:传送速度快,具有较高的传输速率;总线控制逻辑简单。
缺点:主从设备属于强制性同步;不能及时进行数据通信的有效性检验,可靠性较差。
同步通信适用于总线长度较短及总线所接部件的存取时间比较接近的系统。
根据"请求"和"回答"信号的撤销是否互锁,分为以下3种类型:
主机如何与I/O设备进行交互:通过I/O接口,又称I/O控制器、设备控制器
CPU和外设之间的速度差距是很大的,所以我们需要有数据寄存器来作为缓冲,一个慢速的外设可以往数据寄存器里慢慢的写入数据,当这个寄存器被写满,CPU很快的将这个寄存器的数据取走。

I/O接口的工作原理:CPU连接在左边主机侧,然后外设(例如打印机)连接在右边设备侧
控制寄存器、状态寄存器在使用时间上是错开的,因此有的I/O接口中可将二者合二为一。 IO控制器的各种寄存器称为IO端口。例如数据缓冲寄存器称为数据端口,状态寄存器称为状态接口。

I/O端口就是一个一个的寄存器。由于I/O接口内部有很多端口(寄存器),为了标明CPU要访问的是哪个寄存器,因此我们就需要给这些端口(寄存器)进行编址。 CPU对于不同端口(寄存器)的操作是不一样的:
对于数据端口(寄存器)既可以读也可以写
对于控制端口(寄存器)只能写
对于状态端口(寄存器)只能读
统一编址:把I/O端口当做存储器的单元进行地址分配,用统一的访存指令就可以访问I/O端口,又称存储器映射方式(意思就是I/O端口的地址和内存的地址是一整套)
靠不同的地址码区分内存和I/O设备,I/O地址要求相对固定在地址的某部分
LOAD指令,只要可以访问内存也可以访问I/O端口独立编址: I/O端口地址与存储器地址无关,独立编址CPU需要设置专门的输入/输出指令访问端口,又称I/O映射方式(意思就是I/O端口的地址和内存的地址是相互独立的)

程序查询方式:CPU启动I/O操作之后,例如启动一个读操作,当I/O设备在准备数据的时候, CPU会不断的轮巡检查I/O接口当中这个状态是否已完成,当CPU发现I/O设备的数据准备完成之后, CPU才会去I/O接口当中取走数据。在I/O设备准备数据的这个过程当中,CPU不可以干其他事情, CPU需要一直轮巡检查I/O接口状态。
程序中断方式:每一次I/O设备(外设)准备好一个字的数据, CPU就需要运行一次中断服务程序,把这一个字的数据转存到主存当中,所以对于那些速度很快的I/O设备来说,采用这种中断控制方式,会使CPU执行中断服务程序开销很大,效率很低
DMA方式:DMA控制器也是一种I/O控制器,也就是I/O接口。在数据准备阶段,CPU与外设并行工作, DMA方式在外设与内存之间开辟一条直接数据通路,信息传送不再经过CPU,降低了CPU在传送数据时的开销,因此称为直接存储器存取方式。由于数据传送不经过CPU,也就不需要保护恢复CPU现场等操作

在这种控制方式下,CPU一旦启动I/O,就必须停止现行程序的运行,并在现行程序中插入一段程序。
CPU处理中断的基本流程:
CPU如何判断自己当前处于关中断的状态呢?这个信息会被记录在PSW状态寄存器里面,当IF=1表示开中断(允许响应中断),IF=0表示关中断(不允许响应中断)。关中段可以用来辅助原子操作。
中断请求标记:判断是哪个设备发来的中断信号。每个中断源向CPU发出中断请求的时间是随机的。为了记录中断事件并区分不同的中断源,中断系统需对每个中断源设置中断请求标记触发器INTR,当其状态为"1"时表示中断源请求。这些触发器可组成中断请求标志寄存器,该寄存器可集中在CPU中,也可分散在各个中断源中。

通过INTR线发出的是可屏蔽中断,也就是外中断,对于外中断,CPU是在统一的时刻即每条指令执行阶段结束前向接口发出中断查询信号,以获取I/O的中断请求,也就是说,CPU响应中断的时间是在每条指令执行阶段的结束时刻。
CPU响应中断必须满足以下三个条件:
中断判优:有多个中断信号同时到来,先处理哪一个中断
中断判优既可以用硬件实现,也可以用软件实现:


如上图,在K指令执行结束后发现了一个中断信号,此时我们需要让PC指向该中断处理程序的第1条指令的地址,但是由于此时PC指向的是K+1条指令,现在这个中断事件导致程序执行流发生了改变,所以CPU处理完中断之后,又需要将PC的值指向K+1。
中断服务程序的主要任务:
正常情况,CPU取一条指令执行一条指令,取一条指令执行一条指令,顺序执行各条指令。在每条指令的末尾,CPU都会检查是否有中断信号,若没有中断信号需要处理,则继续取下一条指令执行下一条指令。若有中断信号需要处理:
单重中断:执行中断服务程序时,不响应新的中断请求
- 因为关中断和开中断保证了中断服务程序一气呵成,即使此时有新的中断请求也不会响应
单重中断:在CPU执行中断服务程序的过程中,又出现了新的更高优先级的中断请求,而CPU对新的中断请求不予响应,则这种中断称为单重中断
多重中断:又称中断嵌套,执行中断服务程序时可响应新的中断请求。(也就是执行中断服务程序时又发生了中断, CPU暂停现行的中断服务程序转去处理新的中断请求)

保护现场和恢复现场的操作都必须一气呵成
多重中断其实就是又增加了一条关中断和开中断,并且多层中断,在保护现场时也会保护屏蔽字。屏蔽字也叫中断屏蔽字,他可以屏蔽某些中断
中断屏蔽技术主要用于多重中断,CPU要具备多重中断的功能,须满足下列条件:
每个中断源都有一个屏蔽触发器,1表示屏蔽该中断源的请求,0表示可以正常申请,所有屏蔽触发器组合在一起,便构成一个屏蔽字寄存器,屏蔽字寄存器的内容称为屏蔽字

左边是硬件排队器,右边是增加了中断屏蔽功能的硬件排队器.
屏蔽字设置的规律:
DMA的传送过程:
到底要让谁使用主存,这个操作完全由CPU控制,因为CPU将总线给了DMAC就意味着CPU不能访问主存
由于DMA方式传送数据不需要经过CPU,因此不必中断现行程序,I/O与主机并行工作,程序和传送并行工作。
DMA方式具有下列特点:
| 中断 | DMA | |
|---|---|---|
| 数据传送 | 程序控制 程序的切换 -> 保存和恢复现场 | 硬件控制 CPU只需进行预处理和后处理 |
| 中断请求 | 传送数据 | 后处理 |
| 响应 | 指令执行周期结束后响应中断 | 每个机器周期结束均可,总线空闲即可响应DMA请求 |
| 场景 | CPU控制,低速设备 | DMA控制器控制,高速设备 |
| 优先级 | 优先级低于MDA | 优先级高于中断 |
| 异常处理 | 能处理异常事件 | 仅传送数据 |