四. 指令系统1. 指令格式2. 扩展操作码3. 指令寻址3.1 顺序寻址3.2 跳跃寻址4. 数据寻址4.1 直接寻址4.2 间接寻址方式4.3 寄存器寻址4.4 寄存器间接寻址4.5 隐含寻址4.6 立即寻址4.7 偏移寻址基址寻址变址寻址相对寻址4.8 堆栈寻址5. 高级语言与机器级代码之间的对应5.1 x86汇编语言指令基础5.2 常用的汇编指令5.3 AT&T格式的汇编指令5.4 汇编选择语句5.5 循环语句的汇编实现5.6 函数调用汇编实现栈帧中数据的访问切换栈帧栈帧中包含的内容函数参数与返回值的传递6. CISC和RISC五. 中央处理器1. CPU的功能和基本结构1.1 运算器基本结构1.2 控制器内部基本结构2. 指令执行过程2.1 CPU处理各种指令的周期2.2 四个执行周期执行原理取址周期间址周期中断周期2.3 指令执行方案3. 数据通路3.1 CPU内部单总线方式寄存器之间的数据传送主存与寄存器之间的数据传送单总线方式例题3.2 专用数据通路4. 控制器的设计4.1 硬布线控制器设计设计思路设计方式4.2 微程序控制器的基本原理微程序控制器基本结构微指令设计4.3 微指令的编码方式直接编码方式字段直接编码字段间接编码方式微指令地址形成方式4.4 微程序控制单元的设计4.5 微程序设计分类与两种设计方式对比5. 指令流水线5.1 影响指令流水线的因素结构相关因素数据相关控制相关5.2 指令流水线的分类5.3 流水线的多发技术5.4 五段式指令流水线运算类指令LOAD指令STORE指令条件转移指令无条件转移指令6. 多处理器系统6.1 SISD、SIMD、MIMD的基本概念6.2 硬件多线程概念六. 总线1. 总线的概述2. 评价总线性能的指标3. 总线的操作和定时七. 输入
即便是对于同一台计算机,所支持的指令类别也是千差万别的。各种各样的指令应该如何设定是这一章重点探讨的内容。
指令的定义(机器指令):是指示计算机执行某种操作的命令,是计算机运行的最小功能单位。而一台计算机的所有指令的集合构成该机的指令系统,也称为指令集。
注:一台计算机只能执行自己指令系统中的指令,不能执行其他系统的指令。如:x86架构、ARM架构。
一条指令就是机器语言的一个语句,它是一组有意义的二进制代码。一条指令格式通常要包括操作码字段和地址码字段两部分:
由于各种指令所需要的操作不一样,所以地址码的数目也有可能会出现变化。所以一条指令可能包含
零地址指令(OP)
零地址指令只需要指明操作码即可。通常两种情况需要用到零地址指令:
不需要操作数,如空操作、停机、关中断等指令。
堆栈计算机,两个操作数隐含存放在栈顶和次栈顶,计算结果压回栈顶。
这种情况并不是不需要操作数,而是操作数会固定隐含在特定的位置。
如:后缀表达式,堆栈型计算机在进行算术表达式运算的时候是基于后缀表达式实现的,在计算过程中操作数是隐含在栈中的而不是在指令中。
一地址指令(OP
需要指明操作码和一个操作对象。通常两种情况会用到一地址指令:
只需要单操作数,如加
所以完成这条指令需要
需要两个操作数,但其中一个操作数隐含在某个寄存器(如隐含在ACC中)。
指令含义:将ACC累加寄存器中存放的数据,还有
所以完成这一条指令需要
注意:上面
二地址指令(OP
常用于需要两个操作数的算术运算、逻辑运算相关指令。
指令含义:
完成这一次指令需要
三地址指令
常用于需要两个操作数的算术运算、逻辑运算相关指令。
指令含义:
完成这一次指令需要
四地址指令
指令含义:
完成这一次指令需要
正常情况下在取指令之后指针
对于
还可以对指令进行其他分类,先来看以下概念:
指令字长:一条指令的总长度(可能会变)
机器字长:与CPU有关,CPU进行一次整数运算所能处理的二进制数据的位数(通常和ALU直接相关)
存储字长:与主存有关,一个存储单元中的二进制代码位数(通常和MDR位数相同)
可能会见到半字长指令、单字长指令、双字长指令这些术语。这指的是指令长度是机器字长的多少倍。通常情况下指令字长会影响取指令所需时间。如:机器字长
存储字长 ,则取一条双字长指令( )需要两次访存。
所以可以对指令按照长度进行分类:
有的系统中所有指令的长度都相等,这称作定长指令字结构。
对于一个定长操作系统,如果操作码是
而有的系统中各种指令的长度不等,这称作变长指令字结构。
控制器译码电路设计复杂,但灵活性高。
按照操作类型分类:
数据传送
LOAD作用:把存储器中的数据放到寄存器中
STORE作用:把寄存器中的数据放到存储器中
算术逻辑操作
算术:加减乘除、增
逻辑:与、或、非、异或、位操作、位测试、位清除、位求反
移位操作
算术移位、逻辑移位、循环移位(带进位和不带进位)
转移操作
无条件转义(JMP)
有条件转义:JZ(结果为
调用和返回:CALL和RETURN
陷阱(Trap)与陷阱指令
输入输出操作
CPU寄存器和IO端口之间的数据传送(端口即IO接口中的寄存器)
定长指令字结构
举例:如果指令字长为
前
这么做,CPU可以在取得一条
同样,如果满足开头
接着,如果前
在设计扩展操作码指令格式时,必须注意以下两点:
通常情况下,对使用频率较高的指令,分配较短的操作码;对使用频率较低的指令,分配较长的操作码。尽可能减少指令译码和分析的时间。如:对于二地址指令操作码是
例题:设指令字长固定为
要求 | 格式 | 起始指令位 | 指令位 | 指令位 | 指令位 |
---|---|---|---|---|---|
a.有 | |||||
b.有 | |||||
c.有 | |||||
d.有 |
对于有
条三地址指令:其只要满足前四位不大于 即可。 有
条二地址指令:前四位固定,并且要留八位给两个地址,所以只有 位可以当作指令, 可以代表 个不同二进制数即指令。 有
条一地址指令:前六位要区分指令位,所以全 ,另外还要留 位做地址位,只剩 位可以用于做分配的指令位。 就可以表示 不同二进制位,即指令。 有
条零地址指令:前 位区分指令位,所以全 ,没有地址位,所以剩下的 位可以用来表示指令位。 可以表示正好可以表示 中状态,即指令。
这样设计好后,CPU可以根据开头几位确定是哪种地址指令。如:前
上面设计方法可以得出一个结论:设地址长度为
指令寻址:下一条欲执行指令的指令地址。这个地址始终由程序计数器PC给出。并且有顺序寻址和跳跃寻址两种方式。
CPU可以通过顺序寻址和跳跃寻址方式,确定下一条指令的存放地址。
程序计数器
上图给出一个系统,该系统采用定长指令字结构,指令字长
但有的系统会采用按字节编址方式,即每条指令会占两个地址。此时
当然有的系统也会采用变长的指令字结构:
如上图,颜色相同的是一个指令。PC会先指向第一个指令地址
以上都是按照顺序寻址方式,这种方式
给出一个系统,该系统采用定长指令字结构,指令字长
PC初始值指向
这种通过转移类指令,改变PC的值,即改变程序执行流的方式称为跳跃寻址。
数据寻址:确认本条指令码的地址码指明的真实地址。
指令是操作码
增加
根据中间寻址特性来确认这个形式地址应该用十种方法哪一种来解析它,得到真正的真实地址,这个真实地址叫有效地址(EA)。
上面是对于一地址指令,二地址指令如下:
在接下来的介绍中,为了方便,假设指令字长
直接寻址:指令字中的形式地址
CPU根据指令的寻址特征知道这是直接寻址,会根据形式地址
这种寻址访存次数:取指令访存
直接寻址优点:简单,指令执行阶段仅访问一次主存,不需专门计算操作数的地址。
直接寻址缺点:
间接寻址:指令的地址字段给出的形式地址不是操作数的真正地址,而是操作数有效地址所在的存储单元的地址,也就是操作数地址的地址,即
CPU根据寻址特征知道这是间接寻址,根据形式地址
寻址访存次数:取指令访存
同时还有两次间接寻址:
根据形式地址
间接寻址优势:可扩大寻址范围(有效地址
缺点:指令在执行阶段要多次访存(一次间址需两次访存,多次寻址需根据存储字的最高位确定几次访存),导致寻址效率变低。
寄存器寻址:在指令字中直接给出操作数所在的寄存器编号,即
CPU根据寻址特征知道这是寄存器寻址,所以形式地址不是指向主存中的位置,而是寄存器中的位置。CPU内部会有很多通用寄存器,根据形式地址
寻址访存次数:取指令访存
寄存器寻址优点:指令在执行阶段不访问主存,只访问寄存器,由于CPU中寄存器不会太多,所以指令字短且执行速度快,支持向量
寄存器寻址缺点:寄存器价格昂贵,计算机中寄存器个数有限。
寄存器间接寻址:寄存器
CPU根据寻址特征知道这是寄存器间接寻址,根据形式地址指明的寄存器编号,而这个寄存器编号中的内容才是有效地址
寻址访存次数:取指令访存
寄存器间接寻址特点:与一般间接寻址相比速度更快,但指令的执行阶段需要访问主存(因为操作数在主存中)。
隐含寻址:不是明显地给出操作数的地址,而是在指令中隐含着操作数的地址。
有的地址显示给出的地址只是指明,其中一个操作数的位置,而另一个操作数会默认在ACC累加寄存器中,但是这个操作数并没有在指令中显示的给出,所以这是隐含寻址。
优点:有利于缩短指令字长。
缺点:需增加存储操作数或隐含地址的硬件。
立即寻址:形式地址
寻址访存次数:取指令访存
立即寻址优点:指令执行阶段不访问主存,指令执行时间最短。
立即寻址缺点:
六种寻址方式总结:
以某个地址作为起点,形式地址视为偏移量。偏移寻址有三种:相对寻址、基址寻址和变址寻址。
上图最左边
这三种偏移方式区别在于偏移的起点不一样。
基址寻址:将CPU中基址寄存器(BR)的内容加上指令格式中的形式地址
有的计算机会带有基址寄存器:
采用这种基址寄存器,则指令中还有形式地址
注:可对比操作系统OS课中的"重定位寄存器"就是"基址寄存器"。
而有的计算机内部不会有专门的基地址寄存器,而是使用某个通用寄存器。
CPU根据寻址特征知道这是基址寻址,另外还需要花几个比特位指明基地址存放在通用寄存器哪个位置。上图指明存放在通用寄存器
其中
优点:可扩大寻址范围(基址寄存器的位数大于形式地址A的位数);用户不必考虑自己的程序存于主存的哪一空间区域,故有利于多道程序设计,以及可用于编制浮动程序便于程序"浮动",可以从内存当中任何一个地址作为程序起始地址,方便实现多道程序并发运行。
注:基址寄存器是面向操作系统的,其内容由操作系统或管理程序确定。在程序执行过程中,基址寄存器的内容不变(作为基地址),形式地址可变(作为偏移量)。当采用通用寄存器作为基址寄存器时,可由用户使用汇编语言决定哪个寄存器作为基址寄存器,但其内容仍由操作系统确定。
变址寻址:有效地址
如果计算机中有变址寄存器
采用这种基址寄存器,则指令中还有形式地址
可以发现变址寻址和基址寻址方式一样。他们的区别在于,变址寄存器是面向用户的,在程序执行过程中,变址寄存器的内容可由用户改变。另外
变址寻址原理:先给出一段程序
xxxxxxxxxx
31for(int i=0; i<10; i++){
2 sum+=a[i];
3}
该程序存储结构如下:
sum+=a[i]
。i++
。i<10
从上面可以体会到,i
。不断改变变址寄存器
变址寻址优点:在数组处理过程中,可设定
复合寻址:
可以采用基址
如果一个程序在主存中随机存放,就需要一个基地址指向程序的起始位置。此时
注:实际应用中往往需要多种寻址方式复合使用(可理解为复合函数)
相对寻址:把程序计数器
先从主存地址
相对寻址原理:
当执行到-4(补码表示)
,此时
同时还能发现一个问题,当程序代码移动时,数组
采用相对寻址优点:操作数的地址不是固定的,它随着
注意:基址寻址中的浮动指的是整段程序在内存中的浮动。而相对寻址的浮动指的是一段代码在程序内部的浮动。
三种寻址方式总结:
注意:取出当前指令后,PC会指向下一条指令,相对寻址是相对于下一条指令的偏移
堆栈寻址:操作数存放在堆栈中,隐含使用堆栈指针(SP)作为操作数地址。这个堆栈指针存放在寄存器
堆栈是存储器(或专用寄存器组)中一块特定的按后进先出(LIFO)原则管理的存储区,该存储区中被读
这个堆栈可以用两种方式实现:一种是采用专门寄存器存放专门元素。另一种方式是在主存中划出一片区域用作堆栈。
用寄存器实现堆栈原理:
这里用四个寄存器实现堆栈,系统中会用专门的寄存器
假设现在要用堆栈里的两个栈顶元素来完成一次加法操作。加数和被加数会先放到
汇编指令如下:
上面情况是栈顶在小地址方向,还有的情况是栈顶在大地址方向。栈顶大地址方向的汇编指令:
上面通过几个寄存器实现的堆栈称为硬堆栈。还有一种方式是软堆栈,即从主存中划出一片区域当堆栈。这种方式通过POP和PUSH对栈进行操作都会进行一次访存,而硬堆栈由于存放在寄存器中所以不用进行访存。
显然采用寄存器实现的硬堆栈速度更快,但成本高;而软堆栈访问速度慢,但成本更低。在实际的系统中通常采用软堆栈实现。堆栈可用于函数调用时保存当前函数的相关信息。
十种寻址方式总结:
机器语言与汇编语言都是机器级代码。考试只考x86汇编语言,如果考察其他汇编语言题中会给出详细注释。
指令作用:要么处理数据,要么改变程序执行流。指令的格式:操作码
以
语法格式 | 功能 |
---|---|
将源操作数 |
1mov eax,ebx #将寄存器ebx的值复制到寄存器eax
2mov eax,5 #将立即数5复制到寄存器eax
3mov eax,dword ptr[af996h] #将内存地址af996h所指的32bit值复制到寄存器eax
4mov byte ptr[af996h],5 #将立即数5复制到内存地址af996h所指的--字节中
上面中括号表示主存地址。
如何指明内存的读写长度:dword ptr:双字(32bit);word ptr:单字(16bit);byte ptr:字节(8bit)
x86架构的CPU,寄存器如下:寄存器
前四个为一组用于存什么数据未知,所以称为通用寄存器。
中间两组
最后两个寄存器
前四个寄存器使用较为灵活,可以去掉前面的
并且可以指定使用
当然最常用的还是直接使用
在看几个常见操作:
xxxxxxxxxx
71mov eax,dword ptr [ebx] #将ebx所指主存地址的32bit复制到eax寄存器中
2mov dword ptr [ebx],eax #将eax的内容复制到ebx所指主存地址的32bit
3mov eax, byte ptr [ebx] #将ebx所指的主存地址的8bit复制到eax
4mov eax,[ebx] #若未指明主存读写长度,默认32 bit
5mov [af996h],eax #将eax的内容复制到af996h所指的地址(未指明长度默认32bit)
6mov eax,dword ptr [ebx+8] #将ebx+8所指主存地址的32bit复制到eax寄存器中
7mov eax, dword ptr [af996-12h] #将af996-12所指主存地址的32bit复制到eax寄存器中
x86常见的算术运算指令:
功能 | 汇编指令 | 解释 |
---|---|---|
加 | add d,s | 计算 |
减 | sub d,s | 计算 |
乘 | mul d,s imul d,s | 无符号数 有符号数 |
除 | div s idiv s | 无符号数除法edx:eax/s, 商存入eax, 余数存入edx 有符号数除法edx:eax/s, 商存入eax, 余数存入edx |
取负数 | neg d | 将 |
自增 | inc d | 将 |
自减 | dec d | 将 |
上面指令后的操作数可能来自寄存器、主存和指令这三个地方。而为了提高运行效率减少主存访问,在x86汇编指令中两个操作数不能同时来自主存。由于最终处理的结果要放回到
注意除法指令,
通常会用<reg>
代表寄存器、<mem>
代表内存、<con>
代表常数。
x86常见的逻辑指令
功能 | 汇编指令 | 解释 |
---|---|---|
与 | and d,s | 将 |
或 | or d,s | 将 |
非 | not d | 将 |
异或 | xor d,s | 将 |
左移 | shl d,s | 将 |
右移 | shr d,s | 将 |
其他指令:
用于实现分支结构、循环结构的指令:cmp、test、jmp、jxxx
用于实现函数调用的指令:push、pop、call、ret
用于实现数据转移的指令:mov
AT&T格式常用于Unix和Linux。intel格式常用于Windows。
AT&T常用格式:
功能 | 汇编指令 | 解释 | 对应intel格式 |
---|---|---|---|
目的操作数 | op s,d | 源操作数在做,目的操作数在右 | op d,s |
寄存器表示 | mov %ebx,%eax | 寄存器名前必须加" | mov eax,ebx |
立即数的表示 | mov | 立即数之前必须加" | mov eax,985 |
主存地址的表示 | mov %eax,(af996h) | 主存地址用小括号表示 | mov [af996h],eax |
读写长度的表示 | movb movw movl addl | 指令后加 长度byte、word、dword | mov byte ptr [af996h],5 mov word ptr [af996h],5 mov dword ptr [af996h],5 add byte ptr [af996h],4 |
主存地址偏移量的表示 | movl -8(%ebx),%eax movl 4(%ebx,%ecx,32),%eax | 偏移量(基址) | mov eax,[ebx-8] mov eax,[ebx+ecx*32+4] |
对于最后mov eax,[ebx+ecx*32+4]
,做一下详细解释:
对于上图,这是一个结构体数组。要访问数据元素
前面已经介绍基本汇编语句,这里会介绍选择语句的汇编方式。
指令存储在主存中,每次取出一条指令
改变程序执行流需要用到无条件转义指令:JMP
指令名 | 语法 | 功能 |
---|---|---|
jmp | jmp <地址> | PC无条件转移至地址处 |
这里的<地址>
可以是常数、寄存器、主存。但最常用还是"标号"锚定:
xxxxxxxxxx
61mov eax,7
2mov ebx,6
3jmp NEXT
4mov ecx, ebx
5NEXT : #用"标号”锚定位置
6mov ecx, eax
当执行到jmp NEXT
时,程序计数器NEXT
标记的位置。这里的标号不一定是NEXT
,可以自定义名字。
JMP指令类似于C语言的goto语句,虽然能实现跳转,但无法实现if...else..
语句。要实现选择语句需要用到条件转移指令jxxx
。
常用的jxxx
语句及功能:
语句 | 语法 | 功能 |
---|---|---|
je | je <地址> | 若a==b 则跳转 |
jne | jne <地址> | 若a!=b 则跳转 |
jg | jg <地址> | 若a>b 则跳转 |
jge | jge <地址> | 若a>=b 则跳转 |
jl | jl <地址> | 若a<b 则跳转 |
jle | jle <地址> | 若a<=b 则跳转 |
上面指令通常要搭配CMP指令,CMP指令用于比较两个数。
语法 | 功能 |
---|---|
cmp a,b | 比较 |
例1:
xxxxxxxxxx
21cmp eax,ebx #比较寄存器eax和ebx里的值
2jg NEXT #若eax > ebx,则跳转到NEXT:
例2:将下面C语言转换为汇编语言
xxxxxxxxxx
51if(a>b){
2 c=a;
3}else{
4 c=b;
5}
汇编语言:
xxxxxxxxxx
91mov eax,7 #假设变量a=7,存入eax
2mov ebx,6 #假设变量b=6,存入ebx
3cmp eax,ebx #比较变量a和b
4jg NEXT #若a>b,转移到NEXT:
5mov ecx,ebx #假设用ecx存储变量c,令c=b
6jmp END #无条件转移到END :
7NEXT:
8mov ecx,eax #假设用ecx存储变量c,令c=a
9END:
扩展:CMP指令的底层原理。
之前学习过,每次ALU运算都会产生新的标志位覆盖上次标志位:
而跳转指令JMP之前会使用CMP指令,这个指令本质是将做一次
jne
这条指令在a!=b
时发生跳转,CPU在执行这条指令时,会读取之前CMP产生的标志位
xxxxxxxxxx
61je <地址> #若a==b则跳转,ZF==1?
2jne <地址> #若a!=b则跳转,ZF==0?
3jg <地址> #若a>b则跳转,ZF==0&&SF==OF?
4jge <地址> #若a>=b则跳转,SF==OF?
5jl <地址> #若a<b则跳转,SF!=OF?
6jle <地址> #若a<=b则跳转,SF!=OF||ZF==1?
可以用条件转移指令实现循环。有以下C语言代码:
xxxxxxxxxx
41int resul=0;
2for(int i=1;i<=100;i++) {
3 result +=i;
4} //求1+2+3+. . .+100
转换为汇编语言:
xxxxxxxxxx
101mov eax,0 #用eax保存result,初值为0
2mov edx,1 #用edx保存i, 初始值为1
3cmp edx,100 #比较i和100
4jg L2 #若i>100,转跳到L2执行
5L1: #循环主体
6add eax,edx #实现result +=i
7inc edx #inc自增指令,实现i++
8cmp edx,100 #比较i和100
9jle L1 #若i<=100,转跳到L1执行
10L2: #跳出循环主体
所以用条件转移指令实现循环,需要
除了用条件转移指令实现,还可以用LOOP指令。
指令语法 | 功能 |
---|---|
loop 循环体名 | 循环计数器 |
实现:有以下一段C语言
xxxxxxxxxx
31for(int i=500;i>0;i--){
2 //...
3}//循环500次
使用LOOP指令实现循环:
xxxxxxxxxx
51mov ecx,400 #用ecx作为循环计数器
2Looptop: #循环体
3#...
4#...
5loop Looptop #ecx--,若ecx!=0,则跳转到Looptop循环体
上面汇编代码可以知道LOOP指令相当于:
xxxxxxxxxx
31dec ecx
2cmp ecx,0
3jne Looptop
注意:ecx可以作为循环计数器,其寄存器不能,所以这里必须用ecx寄存器。
理论上能用loop指令实现的功能一定能用条件转移指令实现。而使用loop指令可能会使代码更清晰简洁。
补充:loop指令还有loopx指令。如loopnz,和loopz。其中loopnz是当ecx!=0&&ZF==0
时,继续循环。而loopz是当ecx!=0&&ZF==1
时,继续循环。
高级语言在执行函数如main()
函数时,会先将其压入函数调用栈,这个压入的函数称为栈帧。如果main()
函数调用其他函数时,仍会将被调用函数压入函数栈中,称为栈帧。
每个函数的栈帧中包含函数达阔内定义的局部变量和保存函数调用的信息。
其中caller()
和add()
函数代码如下:
x1int caller() {
2 int temp1=125;
3 int temp2=80;
4 int sum=add(templ,temp2);
5 return sum;
6}
7
8int add(int x,int y){
9 return x+y;
10}
对应的汇编代码如下:
xxxxxxxxxx
251#caller()
2caller:
3push ebp
4mov ebp,esp
5sub esp,24
6mov [ebp-12],125
7mov [ebp-8],80
8mov eax,[ebp-8]
9mov [esp+4],eax
10mov eax,[ebp-12]
11mov esp,eax
12call add
13mov[ebp-4],eax
14mov eax,[ebp-4]
15leave
16ret
17#add()
18add:
19push ebp
20mov ebp,esp
21mov eax,[ebp+12]
22mov edx,[ebp+8]
23add eax,edx
24leave
25ret
所以可以知道函数调用指令是:call 函数名
。函数返回指令是:ret
。
其调用执行原理本质就是CPU中程序计数器,指向改变过程。当产生函数调用时,就是让ret
指令也是让
CALL指令作用:
RET指令作用:从函数的栈帧顶部找到
具体执行是:call指令执行时,首先会将
之前看到的函数调用栈实际在内存中是倒过来存放的。
这是因为在内存中,栈底对应的是内存的高地址,栈顶对应的是低地址。
之前学过x86中的寄存器,其中EBP和ESP寄存器分别用于存储堆栈基指针和堆栈顶指针。并且在一个CPU内部只有一个EBP和ESP。
访问栈帧中的数据需要用到push和pop指令。push、pop指令实现入栈、出栈操作。x86默认以
指令语法 | 功能 | 注意事项 |
---|---|---|
push a | 先让ESP减 | |
pop b | 栈顶元素写入 |
例子:
xxxxxxxxxx
51push eax #将寄存器eax的值压栈
2push 985 #将立即数985压栈
3push [ebp+8] #将主存地址[ebp+8]里的数据压栈
4pop eax #栈顶元素出栈,写入寄存器
5pop [ebp+8] #栈顶元素出栈,写入主存地址[ebp+8]
假设当前eax寄存器中的值是
push eax
会先让esp值
push 985
同样先让esp值
push [ebp+8]
,会先让
pop eax
会让
之后的指令执行原理同上。
通过上面例子可以发现push和pop只能对栈顶元素进行操作,这样访问就有限制,还有更灵活的方法mov指令。
可以使用加法指令和减法指令来对esp和edp两个指针进行移动。
例子:
xxxxxxxxxx
61sub esp,12 #栈顶指针-12
2mov[ esp+8],eax #将eax的值复制到主存[esp+8]
3mov [esp+4],958 #将985复制到主存[esp+4]
4mov eax,[ebp+8] #将主存[ebp+8]的值复制到eax
5mov [esp],eax #将eax的值复制到主存[esp]
6add esp,8 #栈顶指针+8
其内存中的结构如下:
sub esp,12
这条指令会让esp指针向下移动三位。
之后执行原理类似。
因此可以用mov指令,结合esp、ebp指针访问栈帧数据可以用减法
当发生函数调用时,需要修改ebp和esp指向,让其指向新的函数顶部和底部。这个切换过程原理如下:
当执行call add
时,会将旧的
被调用函数开头都会有两个指令
xxxxxxxxxx
21push ebp
2mov ebp,esp
第一条指令会把栈底基地址压入栈顶,第二条指令会将ebp指向esp当前位置
这么做当一层函数执行结束要返回之前,总能在当前函数的栈底找到上一个函数基地址。这样既可以恢复ebp寄存器的值。
以上两条指令可以精简为enter
。
之后被调用函数执行对应操作,最函数执行完毕准备ret
返回指令之前,所有函数都会进行两步操作
xxxxxxxxxx
21mov esp,ebp #让esp指向当前栈帧的底部
2pop ebp #将esp所指元素出栈,写入寄存器ebp
第一个指令会让ebp指向esp位置,即指向栈底。第二个指令会让esp所指的栈顶元素出栈放入ebp寄存器中,同时esp
上面两条指令等价于leave
指令。
最后ret指令,由于上一步将esp指向
总结:
每个被调用函数在执行前都会有enter
部分,最后都会有leave
部分。
当前有一段代码
xxxxxxxxxx
101int caller() {
2 int temp1=125;
3 int temp2=80;
4 int sum=add(templ,temp2);
5 return sum;
6}
7
8int add(int x,int y){
9 return x+y;
10}
假设当前运行的是caller()
函数,根据之前内容,可以知道栈帧中通常包含以下内容:
栈帧底部一定是上一层函数栈帧的基址,即edp旧址。
栈帧最顶部一定是返回地址(当前函数的栈帧除外),也就是
通常将局部变量集中存储在栈帧底部区域。C语言中越靠前定义的局部变量越靠近栈顶。
所以只需要将
通常将调用参数集中存储在栈帧顶部区域
如果当前运行的是add
函数,此时edp
指向add
函数栈底位置。此时将
所以一个函数栈内容分布如下:
可以看到中间有空闲未使用区域。这是正常现象因为当使用gcc编译器时,编译器会将每个栈帧大小设置为
栈帧内容总结:
通过上面学习可以知道函数参数通过
有以下一段汇编代码
xxxxxxxxxx
161#caller()
2caller:
3push ebp
4mov ebp,esp
5sub esp,24
6mov [ebp-12],125
7mov [ebp-8],80
8mov eax,[ebp-8]
9mov [esp+4],eax
10mov eax,[ebp-12]
11mov esp,eax
12call add
13mov [ebp-4],eax
14mov eax,[ebp-4]
15leave
16ret
执行完这段汇编程序后,函数栈如下:
之后会执行call add
指令,add函数汇编指令如下:
xxxxxxxxxx
91#add()
2add:
3push ebp
4mov ebp,esp
5mov eax,[ebp+12]
6mov edx,[ebp+8]
7add eax,edx
8leave
9ret
执行完mov ebp,esp
指令后栈帧如下:
之后mov eax,[ebp+12]
和mov edx,[ebp+8]
,分别可以访问到add eax,edx
会将这两个变量相加,相加后的结果再放回
最后执行leave
指令切换上一层函数栈帧,再执行ret
指令让程序回到函数调用后的一行继续执行。
可以看到add函数将返回值写到eax寄存器中。所以caller函数中的mov [ebp-4],eax
就是取返回值的操作。即对应C语言中的sum=add(temp1,temp2)
操作。之后仍会把sum
放入eax寄存器,让上一层函数取返回值,即mov eax [ebp-4]
。由于C语言的返回值只有一个,所以通常会把返回值写入eax中。这样上一层函数直接去eax中取出返回值即可。
至此对函数调用机器级语言进行总结:
最后还有一个问题,当调用者某些值已经存在
CISC和RISC是指令设计的两个方向。
CISC(复杂指令集计算机系统):设计思路是一条指令完成一个复杂的基本功能。代表:x86架构,主要用于笔记本、台式机等。
RISC(精简指令集计算机系统):设计思路是一条指令完成一个基本动作,多条指令组合完成一个复杂的基本功能。代表:ARM架构、手机、平板等。
可以理解为RISC相当于C语言基本语法,而CISC相当关于提供库函数的C语言。再后来的开发中发现典型程序中
比如设计一套能实现整数、矩阵加
CISC设计思路:
除了提供整数的加减乘指令除之外,还提供矩阵的加法指令、矩阵的减法指令、矩阵的乘法指令一条指令可以由一个专门的电路完成。所以这里需要
所以可以采用"存储程序"的设计思想,由多个比较通用的电路配合存储部件来完成更复杂的指令。即可以设计
RISC设计思路:
只提供整数的加减乘指令。
一条指令一个电路,总共只需要设计
由于RISC设计思路的指令都很简单,所以这些指令执行时间都差不多,这个特性可以很方便实现"并行"、"流水线"。
CISC和RISC对比
对比项目 | CISC | RISC |
---|---|---|
指令系统 | 复杂、庞大、丰富 | 简单、精简 |
指令数目 | 一般大于 | 一般小于 |
指令字长 | 不固定 | 定长 |
可访存指令 | 不加限制 | 只有 |
各种指令执行时间 | 相差较大 | 绝大多数在一个周期内完成 |
各种指令使用频度 | 相差很大 | 都比较常用 |
通用寄存器数量 | 较少 | 多 |
目标代码 | 难以用优化编译生成高效的目标代码程序 | 采用优化的编译程序,生成代码较为高效 |
控制方式 | 绝大多数为微程序控制 | 绝大多数为组合逻辑控制(效率更高) |
指令流水线 | 可以通过一定方式实现 | 必须实现 |
本章会基于之前的学习进行补充和完善。
CPU基本构成是:ALU(第二章已学)、寄存器(第三章已学)、中断系统(最后一章)、CU控制单元(本章)。
CPU需要实现以下功能:
指令控制。完成取指令、分析指令和执行指令的操作,即程序的顺序控制。
操作控制。一条指令的功能往往是由若干操作信号的组合来实现的。CPU管理并产生由内存取出的每条指令的操作信号,把各种操作信号送往相应的部件,从而控制这些部件按指令的要求进行动作。
时间控制。对各种操作加以时间上的控制。时间控制要为每条指令按时间顺序提供应有的控制信号。
数据加工。对数据进行算术和逻辑运算。
中断处理。对计算机运行过程中出现的异常情况和特殊请求进行处理。
正常情况下CPU会顺序执行程序,但计算机内会有一些突发的状况(如鼠标单击其他软件),因此需要这种中断处理。当CPU检测到特殊的中断信号后,会转而处理中断程序的一系列指令代码,当中断执行完后再回去执行原本的程序指令。
CPU结构如下:
从运算器和控制器角度对CPU功能进行分类:
运算器会对程序进行加工操作。
控制器:协调并控制计算机各部件执行程序的指令序列,基本功能包括取指令、分析指令、执行指令
接下来会详细探讨运算器和控制器基本结构。
上面介绍过运算器由两部分构成:算术逻辑单元和通用寄存器组。
算术逻辑单元:主要功能是进行算术
通用寄存器组:如AX、BX、CX、DX、SP等,用于存放操作数(包括源操作数、目的操作数及中间结果)和各种地址信息等。其中SP是堆栈指针,用于指示栈顶的地址。
右图中
上面这种连线方式称为专用数据通路:根据指令执行过程中的数据和地址的流动方向安排连接线路。显然这种连接方式由于寄存器数目增加连接线路也会越来越多,所以制造成本会提高。
所以专用数据通路优势:性能较高,基本不存在数据冲突现象,但结构复杂,硬件量大,不易实现。
同时还会存在另一个问题:如果直接用导线连接,相当于多个寄存器同时并且一直向ALU传输数据,显然ALU只需要
解决方案一
使用多路选择器(MUX)。根据控制信号选择一路输出。
假如现在要执行加法指令
解决方法二
使用三态门。每一个三态门可以控制每一路是否输出。
如:
上面是专用数据通路实现方式,还有另一种连接方式:CPU内部单总线方式。
CPU内部单总线方式:将所有寄存器的输入端和输出端都连接到一条公共的通路上。
假如现在要把
这种内部单总线方式结构简单,容易实现,但数据传输存在较多冲突的现象,性能较低。
冲突现象解释:如果现在用
这样的话就可以先把
由于
同时为了方便某些复杂运算的实现,ALU输出端的暂存寄存器还可以增加一些。如:移位功能变为移位寄存器,累加功能变为累加寄存器。不过最常用的做法是在数据总线上多增加一个ACC累加寄存器。
除了以上结构,在寄存器端还会增加一个
除了以上寄存器之外还需要有移位器,对运算结果进行移位操作。如二进制乘法就是加法操作
最后运算器内部还需要提供计数器,用于控制乘除运算的操作步数。
所以运算器内部结构总结如下:
控制器内部总结构:
第一个重要部件
之后取出一条指令后会把这个指令放入指令寄存器
首先这个指令码会送给指令译码器,输入后这个译码器根据操作会将某一段打通。根据译码器输出信号就可以决定接下来是哪些微操作。所以译码器的输出信号会作为微操作信号发生器的输入信号,用来判断该指令对应的微操作序列应该是什么。
由于这些微操作序列执行需要一个先后次序。因此还需要一个时序系统,用于产生时序信号。微操作信号发生器每接受到一个节拍信号就会执行下一个微操作,会发出下一个微操作对应的信号。除了指令信号还需要根据
最后还需要存储器地址寄存器(MAR),指令的地址码通过给
上面MDR的
CPU内部完整结构总结:
上面橙色寄存器是可用于编程的,灰色是不可以编程使用的。
指令周期:CPU从主存中每取出并执行一条指令所需的全部时间。
一个指令周期可以被划分为:取值周期和执行周期两个部分。
指令周期常常用若干机器周期来表示,机器周期又叫CPU周期。一个机器周期又包含若干时钟周期(也称为节拍、T周期或CPU时钟周期,它是CPU操作的最基本单位)。
上图三个周期所需要的时钟周期都为
每个指令周期内机器周期数可以不等,每个机器周期内的节拍数也可以不等。看下边几个例子可以加深对这句话理解。
空指令:CPU在没有任务时候会执行空指令
因此空指令周期只做了取指令这一个操作。所以只包含一个机器周期。
加法指令:首先CPU要取出指令,并分析。之后经过几步微操作实现执行指令。
所以这条指令包含了两个机器周期:取值周期和执行周期。并且这两个机器周期长度可能不一样。
乘法指令:同样CPU要先取指令,之后经过更长时间的微操作执行指令。
所以乘法指令执行周期要比加法执行周期长。
具有间接寻址的指令:CPU取指令,之后很具形式地址取得有效地址称为间址周期。最后再执行指令操作。
带有中断周期的指令:很多指令再取值周期、间址周期和执行周期结束后还有一个中断周期。这个时期CPU会检查是否有中断信号要进行处理。
指令周期执行流程:
CPU可以通过触发器判断现在位于哪个周期。上面四个周期可以设置四个触发器。
一个触发器可以存放
四个工作周期都有CPU访存操作,只是访存的目的不同。取指周期是为了取指令,间址周期是为了取有效地址,执行周期是为了取操作数,中断周期是为了保存程序断点。
上面介绍了CPU四个执行周期:取址周期、间址周期,执行周期和中断周期。
这个周期执行流程有以下几个阶段:
间址周期执行流程有以下几个阶段:
执行周期的任务是根据IR中的指令字的操作码和操作数通过ALU操作产生执行结果。不同指令的执行周期操作不同,因此没有统一的数据流向。所以之后做讨论。
所谓中断就是暂停当前任务取完成其他任务。为了能够恢复当前任务,需要保存断点。一般使用堆栈来保存断点,这里用SP表示栈顶地址,假设SP指向栈顶元素,进栈操作是先修改指针,后存入数据。这个保存断点过程具体实现如下:
显然不同指令指令周期长度不同,当希望可以连续执行多条指令的时候有以下几个方案:
方案一:单指令周期
对所有指令都选用相同的执行时间来完成。即将周期短的指令,增加周期,使其和最长指令执行周期对齐。
指令之间串行执行。指令周期取决于执行时间最长的指令的执行时间。
缺点:对于那些本来可以在更短时间内完成的指令,要使用这个较长的周期来完成,会降低整个系统的运行速度。
方案二:多指令周期
对不同类型的指令选用不同的执行步骤来完成。
指令之间串行执行;可选用不同个数的时钟周期来完成不同指令的执行过程。
缺点:需要更复杂的硬件设计。
方案三:流水线方案
在每一个时钟周期启动一条指令,尽量让多条指令同时运行,但各自处在不同的执行步骤中。
这种方案指令之间并行执行。这种方案最常用会在后面详细介绍。
数据通路:数据在功能部件之间传送的路径。
数据通路的基本结构:
CPU内部单总线方式:将所有寄存器的输入端和输出端都连接到一条公共的通路上。在同一时刻只允许两个部件之间进行数据交换。
CPU内部多总线方式:将所有寄存器的输入端和输出端都连接到多条公共的通路上。
专用数据通路方式:由于ALU有两个输入口,所以每个寄存器要提供两个连线,这里的两根连线是泛指,如果一个寄存器
下面对单总线方式和专用数据通路方式做详细探讨。
无论哪种方式其目的都是为了实现数据流动,这要是数据通路存在本质。一般来说数据流动可以分为三类:
之前提到过内部总线和系统总线概念:
单总线连接方式如下:
注意:上图中
如果将上图PC内容送到MAR中,实现传送操作流程及控制信号为:
标准答题流程:
也可以写为:
其他寄存器之间的数据流通原理类似。先让
比如IR从主存读取指令,实现传送操作的流程及控制信号为:
执行算术或逻辑运算,比如一条加法指令,微操作序列及控制信号为:
上面CU单元通过不同控制信号完成每一次的微操作。上面每一个微操作都至少消耗一个时钟周期。
设有如图所示的单总线结构,分析指令ADD (R0), R1的指令流程和控制信号。其中(R0)代表R0寄存器中存放的是形式地址。
上图中MemR表示主存读信号,MemW表示主存写信号。
操作分三个周期:取址周期、间址周期、执行周期
取址周期
时序 | 微操作 | 有效控制信号 |
---|---|---|
1 | (PC) | PCout,MARin |
2 | M(MAR) | MARout,MemR,MDRinE |
3 | (MDR) | MDRout,IRin |
4 | 指令译码 | |
5 | (PC) |
间址周期
时序 | 微操作 | 有效控制信号 |
---|---|---|
1 | (R0) | R0out,MARin |
2 | M(MAR) | MemR,MARout,MDRinE |
3 | (MDR) | MDRout,Yin |
这里的
执行周期
时序 | 微操作 | 有效控制信号 |
---|---|---|
1 | (R1) | R1out,ALUin,CU向ALU发ADD控制信号 |
2 | (Z) | Zout,MDRin |
3 | (MDR) | MemW,MDRoutE,MARout |
在任何两个需要流通数据的部件之间都建立专用的数据通路。
上图中的
例题:下图是一个简化了的CPU与主存连接结构示意图(图中省略了所有的多路选择器)。其中有一个累加寄存器(ACC)、一个状态数据寄存器和其他
写出上图中
PC输送的是地址,所以送给MAR,故
只有MDR与主存会发生读
简述图中取指令的数据通路
M(MAR)
(MDR)
OP(IR)
简述数据在运算器和主存之间进行存
设数据地址已经在MAR中
取:
存:
简述完成指令LDA X的数据通路(X为主存地址,LDA的功能为(X)
X
M(MAR)
(MDR)
简述完成指令ADD Y的数据通路(Y为主存地址,ADD的功能为(ACC)
Y
M(MAR)
(MDR)
ALU
由于上一题ACC中已经有
简述完成指令STA Z的数据通路(Z为主存地址,STA的功能为(ACC)
Z
(ACC)
(MDR)
通过之前学习知道高级语言编写的代码会翻译成与之对应的指令。而每条指令的执行会被分为四个周期:取址周期(
在一个机器周期内需要通过若干个机器序列来完成这一个周期内需要完成的事情。而每一个机器周期又有若干个时钟周期组成,每个时钟周期又称为节拍。控制单元CU会在每一个节拍内发出一个微命令(信号),用来完成对应的操作。如:微命令
所以微命令和微操作概念是一一对应的。微操作更多是在描述工作要完成什么内容;而微命令是指要完成这个工作所需要发出的控制信号。所以每发出一条微命令就会完成与之对应的一个微操作。并且有的微操作是有可能并行进行的,比如采用专用通路方式,在这种结构下可以完全让多个寄存器之间的数据同时进行并行的流动。因此每个节拍可以完成并行的不冲突的操作。
上图从上到下依次对应四个周期。每一个周期都有三个节拍,在第一个取址周期内第一个节拍
这个例子有以下特质:
综上所述设计控制器核心思想是:根据指令操作码、目前的机器周期、节拍信号、机器状态条件,即可确定现在这个节拍下应该发出哪些"微命令"。
硬布线控制器是是控制当中的一种,即用纯硬件的方式设计控制器。
设计思路:
首先要将指令寄存器IR的
控制单元CU通过译码器连线中的哪一根输入信号有效来判断执行指令是哪一条指令。这样CU就得到了指令操作码。
之后还需要知道执行到哪一个机器周期,因此需要把
事实上这四个触发器集成在CU内部。
接着还需要让CU判断出当前处于机器周期内的第几个节拍,即要给CU一个节拍信号。
节拍信号是由一个节拍发生器发出的。时钟部件会有规律发出脉冲部件,每个脉冲信号就是一个时钟周期,节拍发生器接收到时钟部件发送的脉冲信号之后,都会选择让
最后还需要给CU提供机器状态条件信息。这些状态条件统称为标志,这些标志来自执行单元的反馈信息。如:PSW中的标志位、ACC累加寄存器中的符号位、
接着CU可以根据指令操作码、目前的机器周期、节拍信号、机器状态条件,即可确定现在这个节拍下应该发出哪些"微命令"。所以控制单元每个输出的控制信号对应一个微命令,也就是对应一个操作。
如:要让
实际上所有指令的取址周期,
接着将这个门电路集成在CU中,节拍发生器
所以只要可以写出某个微命令所对应的逻辑表达式,就能确定这个微命令所对应的电路怎么设计。前面
该逻辑表达式对应的电路:最右边
接下来要探讨的是如何得到与一个微操作所对应的电路,知道这个过程就能知道硬布线控制器如何设计。
其设计步骤可以分为四步:
第一步:分析每个阶段的微操作序列
取址周期(所有指令都一样)
间址周期(所有的指令都一样)
执行周期(各个指令执行各不相同,这里取
CLA:clear ACC指令,ACC清零
LDA X:取数指令,把X所指内容取到ACC
JMP X:无条件转义指令
BAN X:条件转义指令,当ACC为负时转移到X
中断周期微操作不再分析,原理类似。
第二步:采用定长机器周期,为
第三步:安排微操作时序。将以上指令每个周期安排在三个节拍内完成。
安排微操作时序原则:
取址周期
间址周期
由于
执行周期
CLA:ACC清零
LDA X:取数指令
JMP X:无条件转移指令
BAN X:条件转移
第四步:电路设计。设计步骤:
列出操作时间表
取址周期
间址周期
执行周期
写出微操作命令的最简表达式。
将以上三个周期内使用到
可以得到微操作命令
可以化简为:
当以上逻辑表达式为
画出逻辑图
设计硬布线控制器步骤总结:
硬布线控制器特点:
指令越多,设计和实现就越复杂,因此一般用于RISC(精简指令集系统)。
如果扩充一条新的指令,则控制器的设计就需要大改,因此扩充指令较困难。
由于使用纯硬件实现控制,因此执行速度很快。微操作控制信号由组合逻辑电路即时产生。
用高级语言写的代码会被翻译成一系列对等的指令。而每条指令执行可以被细分为一个个微操作。可以把一个时序之内同时进行的微操作用一个微指令来指令
如上图微指令
所以程序是由指令序列构成的。微程序是由微指令序列组成,每一种指令对应一个微程序。
要注意的是机器指令是对程序执行步骤的描述而微指令是对指令执行步骤的描述。
可以借鉴之前采用"存储程序"的思想,CPU出厂前将所有指令的"微程序"存入"控制器存储器"中。
注意:微命令与微操作一一对应。而微指令中可能包含多个微命令。
另外微程序和机器指令也是一一对应的,一种机器指令会对应一个微程序,而一个微程序有多个指令序列构成。所以可以说机器指令是对微指令功能的封装。
所以微指令格式是:用
CU控制单元内部引入控制寄存器(CM)。这个CM用于存放各指令对应的微程序,控制存储器可用只读存储器ROM构成,通常在CPU出厂时就把所有微程序写入。每一种机器指令会对应一个微程序,而一个微程序会与一系列微指令序列构成。这些微指令序列在CM中会顺序存放。
为了指明接下来要执行的微指令存放在什么位置,要引入地址寄存器
对于CMAR来说,同样也需要将内部地址送给地址译码器。其功能是将地址码转化为存储单元控制信号。
之后从CM中取出一条微指令,也需要放到CMDR中,别名叫μIR,用于存放从CM中取出的微指令,它的位数同微指令字长相等。
还需要一个微地址形成部件,它的作用是产生初始微地址和后继微地址,以保证微指令的连续执行。根据机器指令操作码部分来确定它所对应的微指令序列对应的首地址。
最后需要一个顺序逻辑,因为微指令序列不一定是顺序的执行。如果有中断发生,微指令序列执行顺序会发生变化。
所以执行一条指令过程是,首先把指令的操作码送给微地址形成部件,用来确定这条指令所对应的微指令序列的起始地址。接着根据顺序逻辑的标志信息确定接下来执行微指令的存放地址,将微指令地址放入CMAR中。之后经过地址译码器译码之后选中CMAR所指向的那条微指令。之后取出这条微指令将其放入CMDR中,而CMDR中包含微指令两个部分信息,第一部分用来描述微指令对应的控制信号,第二部分用于描述接下来要执行的微指令地址,称为下地址。所以执行完这条微指令后,需要把下地址信息送给顺序逻辑,之后顺序逻辑根据标志信息,再决定下一条微指令的存放地址。之后循环。
当前CU会发出什么信号是根据CMDR中的控制字段决定的。如果所有指令的取址周期、间址周期、中断周期所对应的微指令序列都一样,那么可以共享使用。基于这个原因在CM存储器中存储的微指令序列,通常来说取址周期所对应的微程序断只有一份,因为所有机器指令执行在取址阶段要做的微操作都是一样的。所以间址周期和中断周期也都是只存一份。只有执行周期所对应的微程序每个机器指令都是不一样的。
分析取数指令LAD X的执行流程:
首先进入取址周期
执行
当执行完
当执行周期执行完毕后,最后一条微指令的下地址是
考试常考点:
之前说过取址周期、间址周期、中断周期都是一样的,所以微程序是公用共享的。故对于取址周期来说如果某条指令系统中有
因为
条指令对应的执行周期微程序序列都不一样,因此需要设计 个微程序来分别描述这 条指令执行周期要做的事情。另外还需要一个公用的取址周期,所以是 。z
这里没算间址周期和中断周期是因为一些早期的CPU、物联网设备的CPU可以不提供间接寻址和中断功能,因此这类CPU可以不包含间址周期、中断周期的微程序段。
注意:物理上取指周期、执行周期看起来像是两个微程序,但逻辑上应该把它们看作一个整体。因此,一条指令对应一个微程序的说法是正确的。故取址、间址、执行和中断四个周期组成的微程序段看作逻辑上的一个整体,即微程序。
指令周期:从主存取出并执行一条机器指令所需的时间。用于描述指令的执行速度。
微周期(微指令周期):从控制器存储器取出一条微指令并执行相应微操作所需的时间。用于描述微指令执行速度。
如何根据一条微指令来发出相应的控制信号。通过之前的学习可以知道微命令与微操作是一一对应的,一个微命令对应一根输出线。并且有的微命令是可以并行执行的,因此一条微指令可以包含多个微命令。
引入两个概念:
微指令的格式有三种:水平型微指令、垂直型微指令和混合型微指令。
水平型微指令
一条微指令能定义多个可并行的微命令。
操作控制字段较长,采用这种指令格式会导致指令的条数较少,因为一条指令可以完成多个操作。所以指令条数少,但每个指令较长,整体来看横向发展。
优点:微程序短,执行速度快;
缺点:微指令长,编写微程序较麻烦。
垂直型微指令
一条微指令只能定义一个微命令,由微操作码字段规定具体功能。
微操作码字段较短,要完成更多同样功能需要更多的指令,因为每条微指令只能完成一个微操作。所以指令条数多,但每个指令较短。
优点:微指令短、简单、规整,便于编写微程序;
缺点:微程序长,执行速度慢,工作效率低。
混合型指令
在垂直型的基础,上增加一些不太复杂的并行操作。
微指令较短,仍便于编写;微程序也不长,执行速度加快。
重点探讨水平型微指令格式如何设计操作控制字段。即如何用若干个二进制信息表示一系列控制信号。
微指令的编码方式又称为微指令的控制方式,它是指如何对微指令的控制字段进行编码,以形成控制信号。编码的目标是在保证速度的情况下,尽量缩短微指令字长。
又称为直接控制方式。即在微指令的操作控制字段中,每一位代表一个微操作命令。可以某位为
如上图如果像完成
优点:简单、直观,执行速度快,操作并行性好。
缺点:微指令字长过长,
将微指令的控制字段分成若干"段",每段经译码后发出控制信号。
微命令字段分段的原则:
上图
上图
使用这种编码方式可以有效的将微指令总体长度变短。
例:某计算机的控制器采用微程序控制方式,微指令中的操作控制字段采用字段直接编码法,共有
第
所以字段直接编码优点:可以缩短微指令字长。缺点:要通过译码电路后再发出微命令,因此比直接编码方式慢。
一个字段的某些微命令需由另一个字段中的某些微命令来解释,由于不是靠字段直接译码发出的微命令,故称为字段间接编码,又称隐式编码。
如上图,当字段
优点::可进一步缩短微指令字长。
缺点:削弱了微指令的并行控制能力,故通常作为字段直接编码方式的一种辅助手段。
一个微地址由控制字段和下地址两个部分构成,上面介绍了控制字段的设计,接下来介绍下地址的形成方式。
微指令的下地址字段指出
微指令格式中设置一个下地址字段,由微指令的下地址字段直接指出后继微指令的地址,这种方式又称为断定方式。
根据机器指令的操作码形成
当机器指令取至指令寄存器后,微指令的地址由操作码经微地址形成部件形成。
增量计数法
类似于
分支转移法
转移方式:指明判别条件;
转移地址:指明转移成功后的去向。
通过测试网络
即顺序逻辑会接受标志信息,根据这个标志信息再结合当前正在执行微指令的标志信息,来决定接下来应该执行微指令的存放地址。
由硬件直接产生微程序入口地址
第一条微指令地址会由专门硬件产生(用专门的硬件记录取指周期微程序首地址) 中断周期由硬件产生中断周期微程序首地址(用专门的硬件记录)
例题:某计算机采用微程序控制器,共有
即总共需要存储多少条微指令,由于每条指令对应的微程序由
由于
步骤和硬布线控制器设计思路类似。
设计步骤:
分析每个阶段的微操作序列
写出对应机器指令的微操作命令及节拍安排
写出每个周期所需要的微操作(参照硬布线)
补充微程序控制器特有的微操作:
取指周期:
执行周期:
确定微指令格式
根据微操作个数决定采用何种编码方式,以确定微指令的操作控制字段的位数。 根据CM中存储的微指令总数,确定微指令的顺序控制字段的位数。 最后按操作控制字段位数和顺序控制字段位数就可确定微指令字长。
编写微指令码点
根据操作控制字段每-位代表的微操作命令,编写每- -条微指令的码点。
第一步,以取址周期为例:
取指周期微程序控制器的节拍安排
硬布线与微程序控制器设计对比:
唯一区别在最后对于硬布线控制器是把指令的操作码部分送给指令译码器ID,之后ID会发出与操作码相对应那根线的选通信号。
而对于微程序控制器来说只需要把操作码送给微地址形成部件,之后由微地址形成部件来指明这条指令在接下来的执行周期所对应的微程序的起始地址。
以上给出的三条操作指令并不完善,还需要考虑如何读出这三条微指令,及如何转入下一个机器周期。
对于取址周期第一条微指令会固定存放在
另一方面还需要考虑如何转入下一个机器周期。假设取址周期结束后会直接进入执行周期,由于不同指令在执行阶段微程序各不相同,所以在取址阶段的执行结束后,还需要根据当前指令的操作码确定这个指令所对应的微程序的起始地址。因此把指令操作码送给微地址形成部件后,还需要消耗一个节拍,把微地址形成部件指明的地址信息放入CMAR中,即
所完整取指周期微程序控制器的节拍安排如下:
显然微程序控制器需要
第二步:在第一步得到的微操作序列基础上,把可以并行的微操作安排在一个节拍内进行。
之后由于采用微程序控制器,需要加入几个特有的微操作:
在取址周期内
每条微指令结束之后都需要根据当前执行的微指令的下地址信息,来指明接下来要执行的这条微指令的存放地址,即
另外在取址周期最后一条微指令结束后,还需要指明当前执行的机器指令所对应的执行周期的微程序首地址。即
执行周期内
每条微指令结束之后都需要根据当前执行的微指令的下地址信息,来指明接下来要执行的这条微指令的存放地址,即
第三步:需要确定微指令的格式
第四步:编写微指令码点。如采用直接编码方式,可以根据第一步每条微指令所需要执行的微操作信息确定每条微指令的控制码部分哪一位需要为
接下来把这些微指令序列放到CM中即可。
静态微程序设计和动态微程序设计:
静态设计
微程序写入CM中就无需改变,采用ROM
动态设计
通过改变微指令和微程序改变机器指令。
有利于仿真,采用EPROM。
毫微程序设计:微程序设计用微程序解释机器指令。而毫微程序设计用毫微程序解释微程序。
硬布线与微程序设计比较
对比项目 | 微程序控制器 | 硬布线控制器 |
---|---|---|
工作原理 | 微操作控制信号以微程序的形式 存放在控制存储器中,执行指令时 读出即可 | 微操作控制信号由组合逻辑电路 根据当前的指令码、状态和时序, 即时产生 |
执行速度 | 慢 | 快 |
规整性 | 较规整 | 繁琐、不规整 |
应用场合 | CISC CPU | RISC CPU |
易扩展性 | 易扩充修改 | 困难 |
指令流水线可以对指令的执行过程进行优化。
一条指令的执行过程可以分成多个阶段(或过程)。根据计算机的不同,具体的分法也不同。最简单划分方法是划分为三个阶段:取指阶段、分析阶段、执行阶段。
一条指令在不同的阶段所需要使用到的硬件部件是不一样的:
特点是每个阶段用到的硬件不一样。
为了方便分析,设取指、分析、执行
顺序执行方式
一条指令三个阶段完成后,才会进入下一个阶段。
总耗时:
传统冯诺依曼机采用顺序执行方式,又称串行执行方式。
优点:控制简单,硬件代价小。
缺点:执行指令的速度较慢,在任何时刻,处理机中只有条指令在执行,各功能部件的利用率很低。
引入指令流水线:
一次重叠执行方式
第二条指令第一个阶段和上一条指令的最后一个阶段重叠。
总耗时:
优点:程序的执行时间缩短了
缺点:需要付出硬件上较大开销的代价,控制过程也比顺序执行复杂了。
二次重叠执行方式
总耗时:
与顺序执行方式相比,指令的执行时间缩短近
注:也可以把每条指令的执行过程分成
上图是指令执行过程图。
横坐标是指令执行时间
还有另一种描述指令执行过程的图,时空图:
横坐标表示时间
大体上可以用吞吐率、加速比、效率三个指标评价流水线的性能。
吞吐率是指在单位时间内流水线所完成的任务数量,或是输出结果的数量。
对于指令流水线来说,吞吐率就是单位时间内能完成多少条指令。
设指令任务数为
理想情况下,流水线的时空图如下:
一条指令执行
当连续输入的任务
注意:一条指令的执行分为
这里还需要补充装入时间和排空时间的概念:
装入时间:第一条指令从取指一直到结束所需要的时间。
排空时间:最后一条指令从执行到结束所需要的时间。
加速比:完成同样一批任务, 不使用流水线所用的时间与使用流水线所用的时间之比。
设
理想情况下,流水线的时空图如下:
单独完成一个任务耗时为
当连续输入的任务
效率:流水线的设备利用率称为流水线的效率。
设备利用率是硬件设备处于忙碌时间占总时间比例。在时空图上,流水线的效率定义为完成
流水线效率
当连续输入的任务
上面介绍指令流水线的时,各个阶段都是理想情况,这些导致不完美因素就是要探讨的内容。
即一条指令执行分为
这种五段式指令流水线是考试最常考结构,这种流水线被称为
总之在MIPS架构下一条指令执行会被划分为五个阶段,有的指令可能会跳过某些阶段(如访存阶段)。然而为了方便指令流水线安排,所有指令都会安排为五个这样的机器周期。所以在MIPS架构下一定都是五个机器周期。
另一个方面每个周期花费时间不一样。
各个部件耗时假设为上图所示时间。为方便流水线的设计,将每个阶段的耗时取成一样,以最长耗时为准。即此处应将机器周期设置为
现在产生一个问题,如上图中EX阶段应该是在
上面蓝色方框的部件就是暂存寄存器其称为缓冲寄存器,流水线每一个功能段部件后面都要有一个缓冲寄存器,或称为锁存器,其作用是保存本流水段的执行结果,提供给下一流水段使用。
另外需要注意的是上图CPU中的Cache分为两个模块Instruction Cache(存放指令)和Data Cache(存放数据)。指令和数据用两个独立的Cache模块存放是很有意义的,可以使第一阶段和第四阶段所需要使用的硬件部件可以并行工作。
上图含义是:取指阶段根据PC所指向的位置去Instruction Cache中取出数据,取出的数据放入锁存器中。接着进入第二指令译码阶段,这个阶段除了完成指令译码的工作外,还会完成取数的工作,取数指的是将这条指令所需要的操作数从通用寄存器中取出放入锁存器
第二个阶段有可能对某个通用寄存器进行读操作,最后一个阶段有可能会把某个数据写回到通用寄存器。这两个阶段对寄存器的读和写两个操作可能造成一些问题,即影响流水线的因素。
因素可以分为三类:
又叫资源冲突。由于多条指令在同一时刻争用同一资源而形成的冲突称为结构相关。
上图
解决方法:
后一相关指令暂停一周期
资源重复配置:数据存储器
即如果将指令和数据分别放到两个不同的存储器中,那么第一阶段取指阶段和第四个阶段访存阶段所需要访问的寄存器一定是不相同的。
又叫数据冲突。数据相关指在一个程序中,存在必须等前一条指令执行完才能执行后一条指令的情况,则这两条指令即为数据相关。
上图第一条执行一个加法操作,将
解决方法:
把遇到数据相关的指令及其后续指令都暂停一至几个时钟周期,直到数据相关问题消失后再继续执行。可分为硬件阻塞(stall)和软插 入"NOP"两种方法。
采用硬件阻塞:
如果两个指令之间存在数据冲突使用硬件阻塞方式,硬件系统会添加如上图所示地"气泡"。将第二条指令执行时间往后拖三个节拍。此时后面指令就不会造成数据冲突。
同时也可以用软件NOP指令地方式解决。
执行指令时,编译器发现两个指令之间会有数据冲突关系,那么编译器会在这两条指令中间插入三条空指令。每一个空指令的执行也会经过五个周期。之后的指令就不会造成数据冲突问题。
数据旁路技术
又叫做转发机制。其大致思路是在第一条指令ALU进行加法运算结果就已经出来了,此时会连出一个数据旁路,让结果直接送回ALU的其中一个输入端,作为下一条指令的输入。这样就不需要等待上一条指令的写回操作。
编译优化
可以通过编译器调整指令顺序来解决数据相关。
第一条指令结果会被后面指令使用到,如果第五条指令的后面还有其他指令,而这些其他指令又不需要前面几条指令的运算结果,此时就可以将后面几条指令安排在第一条指令之后运行。这样当第二个指令执行时,系统其实已经将第一条指令五个周期全部执行完毕,所以就不会产生数据冲突了。
又叫控制冲突。当流水线遇到转移指令和其他改变PC值的指令而造成断流时,会引起控制相关。
假如现在要执行的是条件转移指令,这条指令存放在上图地址为
解决方法:
转移指令分支预测。与两种预测方式:简单预测(永远猜true或false)、动态预测(根据历史情况动态调整)。
预取转移成功和不成功两个控制流方向上的目标指令
由于条件转移指令,有可能导致程序执行流往两个方向走,那么将两个方向所用到的指令都预取出来。采用这种方法可能会改变硬件,如多增加两个寄存器等。
加快和提前形成条件码。
提高转移方向的猜准率
是对第一种方法优化。
根据流水线使用的级别的不同,流水线可分为部件功能级流水线、处理机级流水线和处理机间流水线。
部件功能级流水就是将复杂的算术逻辑运算组成流水线工作方式。例如,可将浮点加法操作分成求阶差、对阶、尾数相加以及结果规格化等
指令每个阶段所用到的部件不一样,部件级的流水线是把某一阶段用到的功能部件再进一步的细分。如果连续多个同样功能,细分部件可以流水线处理这多个同样功能。
处理机级流水是把一条指令解释过程分成多个子过程,如前面提到的取指、译码、执行、访存及写回
处理机间流水是一种宏流水, 其中每一个处理机完成某一专门任务, 各个处理机所得到的结果需存放在与下一个处理机所共享的存储器中。
让多个CPU,分任务处理。
按流水线可以完成的功能,流水线可分为单功能流水线和多功能流水线。
按同一时间内各段之间的连接方式,流水线可分为静态流水线和动态流水线。
按流水线的各个功能段之间是否有反馈信号,流水线可分为线性流水线与非线性流水线。
线性流水线中,从输入到输出,每个功能段只允许经过一次,不存在反馈回路。
非线性流水线存在反馈回路,从输入到输出过程中,某些功能段将数次通过流水线,这种流水线适合进行线性递归的运算。
如一个ALU计算乘法,但ALU本身不支持乘法,所以只能进行多次加法,并且运算输出端会直接连接到另一个输入端。
超标量技术
每个时钟周期内可并发多条独立指令,即同一时刻同时执行多条指令,是一种空分技术。要想不出现冲突问题,就要配置多个功能部件。并且不能调整指令的执行顺序。
通过编译优化技术,把可并行执行的指令搭配起来。
由于指令的排列是由编译器确定的,因此编译器在得到编译序列的时候要考虑到哪些指令可以并行执行。可以将其搭配在一起。因此对编译优化要求很高。
超流水技术
在一个机器周期内再分段。一个机器周期内一个功能部件使用多次,是一种时分复用技术。
同样不能调制指令的执行顺序。要靠编译程序解决优化问题。上图将每一个机器周期又分为三段,所以速度上提升
超长指令字技术
由编译程序挖掘出指令间潜在的并行性,将多条能并行操作的指令组合成一条超长指令,具有多个操作码字段的超长指令字(可达几百位)
显然多种操作想要同时进行就必须提供多个相互独立的部件。
前面影响指令流水线的因素介绍过五段式指令流水线基本概念。
这里会介绍常见五类指令:运算类指令、LOAD指令、STORE指令、条件转移指令、无条件转移指令详细分析这五类指令如何根据五个功能段完成相应的工作。
运算类指令在不同阶段工作:
指令举例:
功能 | 汇编格式 | 具体描述 |
---|---|---|
加法指令(两个寄存器相加) | ADD Rs,Rd | (Rs) |
加法指令(寄存器与立即数相加) | ADD #996,Rd | 996 |
算术左移指令 | SHL Rd | (Rd) |
上面指令在五个阶段执行如下:
取指阶段(IF)
根据PC从指令Cache中取指令至IF段的锁存器中
译码阶段(ID)
先对指令操作码进行译码。还需要将指令所用到的操作数取到ID段的锁存器中。这一阶段有三个锁存器
执行阶段(EX)
ALU算术逻辑单元根据上个阶段得到得操作数进行运算。运算结果放入EX阶段锁存器中。
访存(M)
在精简系统指令集(RISC)中,运算阶段不需要进行访存,即在这一阶段是空阶段。但是时间仍然需要消耗。
写回阶段(WB)
将执行阶段锁存器中的值放到第四阶段锁存器中,写回阶段会将锁存器中的内容写回到控制器中。
功能 | 汇编格式 | 具体描述 |
---|---|---|
将指定地址中的数据放到某个寄存器中 | LOAD Rd,996(Rs) | (996 |
上面指令在五个阶段执行如下:
取指阶段(IF)
根据PC从指令Cache中取指令至IF段的锁存器中
译码阶段(ID)
将
执行阶段(EX)
将偏移量和基址相加,相加后的结果放入EX段的锁存器中,锁存器中的值就是有效地址EA。
访存阶段(M)
根据刚才锁存器中的有效地址EA从数据Cache中取数并放入访存阶段的锁存器中
写回阶段(WB)
将上一阶段锁存器中的值写回到目的寄存器Rd中。
为了保证流水线的流畅工作,通常访问主存时候,大概率都能在Cache中找到想要的数据。
通常在RISC处理器只有取数指令LOAD和存数指令STORE才能访问主存。
功能 | 汇编格式 | 具体描述 |
---|---|---|
寄存中的值存放会回主存中 | STORE Rs,996(Rd) | Rs |
上面指令在五个阶段执行如下:
取指阶段(IF)
根据PC从指令Cache中取指令至IF段的锁存器中
译码阶段(ID)
将基址寄存器的值放到锁存器
执行阶段(EX)
根据基地址和偏移量计算出有效地址EA,将其放到当前阶段锁存器中。另外还需要将要存放的数即上一阶段
访存阶段(M)
根据有效地址EA将被存的数据放到数据Cache中。随后Cache回同步到主存。
写回阶段(WB)
空阶段
功能 | 汇编格式 | 具体描述 |
---|---|---|
两个寄存器值相等就需要进行转移 | beq Rs,Rt,#偏移量 | 若(Rs) 否则(PC) |
两个寄存器值不相等就需要转移 | bne Rs,Rt,#偏移量 | 若(Rs) 否则(PC) |
上面指令在五个阶段执行如下:
取指阶段(IF)
根据PC从指令Cache中取指令至IF段的锁存器中
译码阶段(ID)
进行比较的两个数放入锁存器
执行阶段(EX)
通过ALU计算将比较结果放入输出端锁存器中
访存阶段(M)
将目标PC值写回PC
很多教材把写回PC的功能段称为"WrPC段"其耗时比M段更短,可安排在M段时间内完成。
写回阶段(WB)
空阶段。这一阶段通常是将值写回寄存器。所以修改PC值不会在这里写回。
功能 | 汇编格式 | 具体描述 |
---|---|---|
根据下一条指令的位置转移到指定位置 | jmp #偏移量(补码表示) | (PC) |
上面指令在五个阶段执行如下:
取指阶段(IF)
根据PC从指令Cache中取指令至IF段的锁存器中
译码阶段(ID)
将偏移量放入
执行阶段(EX)
这一阶段用不到ALU算术逻辑单元。而是回直接根据偏移量将目标的PC值直接写回到PC寄存器中。
"WrPC段"耗时比EX段更短,可安排在EX段时间内完成。WrPC段越早完成,就越能避免控制冲突。当然也有的地方会在WB段时间内才修改PC的值。
访存阶段(M)
空阶段
写回阶段(WB)
空阶段
例题:假设某指令流水线采用"按序发射,按序完成"方式,没有采用转发技术处理数据相关,并且同一寄存器的读和写操作不能在同一个时钟周期内进行。若高级语言程序中某赋值语句为
则这
答案:
与 和 存在数据相关;所以要在 取数指令完成后才能进行编码阶段(ID)。
的 段必须在 进入ID段后才能开始,否则会覆盖 段锁存器的内容。
基于指令流的数量和数据流的数量,对计算机体系结构分为SISD、SIMD、MISD和MIMD四类。常规的单处理器属于SISD,而常规的多处理器属于MIMD。
单指令流单数据流(SISD)结构
SISD是传统的串行计算机结构,这种计算机通常仅包含一个处理器和一个存储器,处理器在一段时间内仅执行一条指令,按指令流规定的顺序串行执行指令流中的若干条指令。为了提高速度,有些SISD计算机采用流水线的方式,因此,SISD 处理器有时会设置多个功能部件,并采用多模块交叉方式组织存储器。前面介绍的内容多属于SISD结构。
所以其特点是各指令序列只能并发、不能并行,每条指令处理一两个数据。
这总系统不支持数据级并行技术。即在同一时刻只能处理一两个特定数据,不可能并行处理很多数据。
若要提升效率可以引入指令流水线,并且需设置多个功能部件,采用多模块交叉存储器。
单指令流多数据流(SIMD)结构
SIMD是指一个指令流同时对多个数据流进行处理,一般称为数据级并行技术。这种结构的计算机通常由一个指令控制部件、多个处理单元组成。每个处理单元虽然都执行的是同一条指令,但每个单元都有自己的地址寄存器,这样每个单元都有不同的数据地址,因此,不同处理单元执行的同一条指令所处理的数据是不同的。一个顺序应用程序编译后,可能按SISD组织并运行于串行硬件上,也可能按SIMD组织并运行于并行硬件上。
SIMD在使用for 循环处理数组时最有效,比如,一条分别对
其特点是各指令序列只能并发、不能并行,但每条指令可同时处理很多个具有相同特征的数据。
该系统是一种数据级的并行技术。
多指令流单数据流(MISD)结构
MISD是指同时执行多条指令,处理同一个数据,实际上不存在这样的计算机。
多指令流多数据流(MIMD)结构
其特点是各指令序列并行执行,分别处理多个不同的数据。是一种线程级并行(每个内核可以运行各自的进程,多个线程并行执行)、甚至是线程级以上并行(进程级并行)技术。
进一步分类可以分为:多处理器系统(共享内存多处理器)和多计算机系统
多处理器系统
其特征是各个处理器之间,可以通过
硬件之间多个处理器共享单一的物理地址空间。
多计算机系统
各个计算机之间主存是独立的,不能通过
每台计算机拥有各自的私有存储器,物理地址空间相互独立。
向量处理机(SIMD思想的进阶应用)
其特点是条指令的处理对象是"向量"。擅长对向量型数据并行计算、浮点数运算,常被用于超级计算机中,处理科学研究中巨大运算量。
其硬件在成采用多个处理单元,多组"向量寄存器"。主存储器应采用"多个端口同时读取"的交叉多模块存储器。主存储器大小限定了机器的解题规模,因此要有大容量的、集中式的主存储器。
总结:
先来看一下不支持多线程的普通处理器:
这个处理器只包含一个同寄存器组和一个PC程序计数器,这就意味着在同一时间段内,在这个处理器当中只可能运行一段程序。如果现在两个线程的代码需要同时运行,那么对于线程
再看可以支持硬件多线程的处理器:
可以看到处理器中设置两个线程寄存器组,这样就可以把线程
接着看三种硬件多线程实现方式:
功能 | 细粒度多线程 | 粗粒度多线程 | 同时多线程(SMT) |
---|---|---|---|
指令发射 | 轮流发射各线程的指令 (每个时钟周期发射一个线程) | 连续几个时钟周期,都发射同一线程的指令序列 当流水阻塞时,切换另一个线程 | 一个时钟周期内,同时发射多个线程的指令 |
线程切换频率 | 每个时钟周期切换一次线程 | 只有流水线阻塞时才切换一次线程 | NULL |
线程切换代价 | 低 | 高,需要重载流水线 | NULL |
并行性 | 指令级并行,线程间不并行 | 指令级并行,线程间不并行 | 指令级并行,线程级并行 |
总线常常分为:地址总线、数据总线和控制总线。
地址总线可以给硬件发送地址信息。数据总线可以传输数据。控制总线可以给部件发送控制信号。
一个总线可以并行传递很多数据是因为每个总线中可能包含多根信号线。
上图是一根数据总线,内部有四根连线,所以可以同时传输
总线是一组能为多个部件分时共享的公共信息传送线路。
共享是指总线上可以挂接多个部件,各个部件之间互相交换的信息都可以通过这组线路分时共享。
分时是指同一时刻只允许有一个部件向总线发送信息,如果系统中有多个部件,则它们只能分时地向总线发送信息。
早期计算机外部设备少时大多采用分散连接方式,即增加一个外部设备就要建立一条专门数据传送线路,这种方式不易实现随时增减外部设备。为了更好地解决
当设计总线的时候需要关注以下特性:
机械特性:尺寸、形状、管脚数、排列顺序
电气特性:传输方向和有效的电平范围
传输方向是指,CPU可以通过地址总线给主存指明此时要读写的地址。显然这个地址总线传输方向只能是由CPU传向主存。对于数据总线来说CPU要往主存中写数据都是通过数据总线传输,所以对于数据总线来说方向是双向的。
有效电平范围:即高低电平在什么样范围内有效。
功能特性:每根传输线的功能(地址、数据、控制)
时间特性:信号的时序关系
串行总线
采用串行总线意味设备
优点:只需要一条传输线,成本低廉,广泛应用于长距离传输;应用于计算机内部时,可以节省布线空间。
缺点:在数据发送和接收的时候要进行拆卸和装配,要考虑串行与并行转换的问题。
并行总线
采用并行总线设备
优点:总线的逻辑时序比较简单,电路实现起来比较容易。
缺点:信号线数量多,占用更多的布线空间;远距离传输成本高昂;由于工作频率较高时,并行的信号线之间会产生严重干扰,对每条线等长的要求也越高,所以无法持续提升工作频率。
显然CPU与主存之间传送数据的总线式并行总线。串行规范常常用于USB。由于各个信号线之间的干扰问题,在发送数据的时候并行总线并不一定比串行要快。
按总线功能(连接的部件)可以分为三类:片内总线、系统总线、通信总线。
片内总线
片内总线是芯片内部的总线。它是CPU芯片内部寄存器与寄存器之间、寄存器与ALU之间的公共连接线。
系统总线
系统总线是计算机系统内各功能部件(CPU、主存、
按系统总线传输信息内容的不同,又可分为
数据总线:传输各功能部件之间的数据信息,包括指令和操作数。其位数(总线的根数)与机器字长、存储字长有关。如果数据总线的宽度和机器字长一致,此时CPU可以进行一次数据读入就可以直接取得数据。信息传递方向是双向的。
地址总线:传输地址信息,包括主存单元或
控制总线:传输控制信息。内部的一根控制线可以传输一个信号。对于一根控制线来说,控制信号的传输方向是单向的。对于整个控制总线来说,有出:CPU送出的控制命令。有入:主存(或外设)返回CPU的反馈信号。
通信总线
通信总线是用于迁算机系统之间或计算机系统与其他系统(如远程通信设备、测试设备)之间信息传送的总线,通信总线也称为外部总线。如网线。
注意:数据通路表示的是数据流经的路径。而数据总线是承载的媒介。
按时序控制方式可以分为两类:同步总线、异步总线
本章重点探讨系统总线,系统总线经典结构有三种:单总线结构、双总线结构、三总线结构。
单总线结构
只会在计算机内部设置一种系统总线。CPU、
这里的系统总线包含数据总线地址总线和控制总线。
优点:结构简单,成本低,易于接入新的设备。
缺点:带宽低、负载重,多个部件只能争用唯一的总线, 且不支持并行传送操作。并且
双总线结构
会让主存、CPU和通道统一的连到一根主存总线上。
通道是具有特殊功能的处理器,专门对
这里的主存总线支持突发(猝发)传送:即送出一个地址,收到多个地址连续的数据。正常来说CPU每指明一个地址,可以从主存当中读出一个字的信息,但是由于主存当中信息很多时候都是需要被连续访问(如指令序列),显然CPU指明地址后如果能从主存当中连续读出多个字的数据,这样系统的效率可能更高。
优点:将较低速的
缺点:需要增加通道等硬件设备。
三总线结构
CPU与主存之间通过主存总线连接。高速外设(磁盘等)可以通过DMA总线有主存进行连接。低速外设(键盘等)通过
对磁盘读写是以块为单位的,让磁盘和主存通过DMA总线交换数据就可以很快完成整块数据的传递。这样做的好处在于CPU不需要通过慢速的
优点:提高了
缺点:系统工作效率较低。原因在于这三个总线同一时间只能有一个总线进行工作。
四总线结构
上面四个总线中,CPU总线最快;其次是系统总线和高速总线;最慢的是扩充总线。所以越靠近CPU的总线速度越快。
由于不同总线之间有速度的差异,因此需要增加一个桥接器部件。桥接器作用是用于连接不同的总线,具有数据缓冲、转换和控制功能。
评价总线性能指标有八种:总线的传输周期(总线周期)、总线时钟周期、总线的工作频率、总线的时钟频率、总线宽度、总线带宽、总线复用、信号线数。
总线传输周期(总线周期)
一次总线操作所需的时间(包括申请阶段、寻址阶段、传输阶段和结束阶段),通常由若干个总线时钟周期构成。有的时候,一个总线周期就是一个总线时钟周期。还有的时候,一个总线时钟周期可包含多个总线周期。
其中申请阶段要做的是总线仲裁,决定是否把总线分配给某个设备使用。寻址阶段是两个设备通过总线进行数据的交互,主设备会通过地址总线将它要读写的地址单元传递给从设备。传输阶段是通过数据总线往从设备中写入数据或读出数据。结束阶段会释放总线的使用权。
经过一个总线周期后可以完成一组数据的传输。假如一组数据总线宽度是
总线时钟周期
即机器的时钟周期。计算机有一个统一的时钟,以控制整个计算机的各个部件,总线也要受此时钟的控制。现在的计算机中,总线时钟周期也有可能由桥接器提供。
总线周期与时钟周期的关系可以是一对一、一对多、多对多。
总线的工作频率
总线上各种操作的频率,为总线周期的倒数。若总线周期
实际上指一秒内传送几次数据。
总线的时钟频率
即机器的时钟频率,为时钟周期的倒数。若时钟周期为
实际上指一秒内有多少个时钟周期。
总线的宽度
又称为总线位宽,它是总线上同时能够传输的数据位数,通常是指数据总线的根数,如
总线带宽
可理解为总线的数据传输率,即单位时间内总线上可传输数据的位数,通常用每秒钟传送信息的字节数来衡量,单位可用字节
总线复用
总线复用是指一种信号线在不同的时间传输不同的信息。可以使用较少的线传输更多的信息,从而节省了空间和成本。
采用这种复用技术,传递地址信息和数据信息时需要两个总线周期,需要两次数据的传送。所以虽然节约成本但是速度有所下降。
信号线数
地址总线、数据总线和控制总线这
通过上面概念可以得到总线带宽公式
由于总线工作频率和总线周期之间是倒数关系,所以
注:总线带宽是指总线本身所能达到的最高传输速率。在计算实际的有效数据传输率时,要用实际传输的数据量除以耗时(校验位等)。
例题:某同步总线采用数据线和地址线复用方式,其中地址
该总线的最大数据传输率(总线带宽)是多少?
每个时钟周期传送两次数据,所以工作频率是时钟频率的两倍,即总线工作频率
总线宽度
总线宽度
若该总线支持突发(猝发)传输方式,传输一个地址占用一个时钟周期,则一次"主存写"总线事务传输
发送首地址占用
故总耗时
由公式
总线同一时刻只能提供给一组设备使用。当一个设备获得总线控制权后,就可以利用总线对某一个从设备发出一定的命令,比如读写数据等。这对主设备和从设备之间怎么用电信号进行数据交流和时序安排就是这一节探讨的内容。
用总线传一次数据,即总线周期需要四个阶段:
而总线定时指的是总线在双方交换数据的过程中需要时间上配合关系的控制,这种控制称为总线定时,它的实质是一种协议或规则。即主模块与从模块在总线周期内进行四个阶段需要时间上的配合进行协调工作,如何进行它们在时间上有条不紊的配合这就是总线定时要探讨的问题。事实上总线定时就是要指定某一种协议或规则让数据的放松方和接受方都能按照统一规则进行数据交互。
总线定时方案(协议)有四种:同步通信(同步定时方式)、异步通信(异步定时方式)、半同步通信、分离式通信。
同步定时方式(读命令)
总线控制器采用一个统一的时钟信号来协调发送和接收双方的传送定时关系。
假设CPU是主设备,某个输入设备作为从设备。假设一个总线传输周期包含
第一个阶段CPU在
第二阶段在
CPU在
CPU在
接着就可以进入下一个总线周期。如果从设备速递较慢,在
所以同步定时方式特点是由若干个时钟产生相等的时间间隔,每个间隔构成一个总线周期。在一个总线周期中,发送方和接收方可进行一次数据传送。因为采用统一的时钟,每个部件或设备发送或接收信息都在固定的总线传送周期中,一个总线的传送周期结束,下一个总线传送周期开始。
优点:传送速度快,具有较高的传输速率;总线控制逻辑简单。
缺点:主从设备属于强制性同步;不能及时进行数据通信的有效性检验,可靠性较差。
因此同步通信方式适用于总线长度较短及总线所接部件的存取时间比较接近的系统。
异步通信方式
在异步定时方式中,没有统一的时钟,也没有固定的时间间隔,完全依靠传送双方相互制约的"握手"信号来实现定时控制。
主设备提出交换信息的"请求"信号,经接口传送到从设备;从设备接到主设备的请求后,通过接口向主设备发出"回答"信号。
可以根据请求和回答信号的撤销是否互锁,进一步细分为以下三类
不互锁方式
当主设备获得主控权之后会发出请求信号(地址信息,读命令)后,不必等到接到从设备的"回答"信,而是经过一段时间便撤销请求信号。
而从设备在接受到"请求"信号后,发出"回答"信号,并经过一段时间,自动撤销"回答"信号。双方不存在互锁关系。
可以看出这种方式信号的撤销不存在相互制约的关系。
半互锁方式
主设备发出"请求"信号后,必须待接到从设备的"回答"信号后,才撤销"请求"信号,有互锁的关系。
而从设备在接到"请求"信号后,发出"回答"信号,但不必等待获知主设备的"请求"信号已经撤销,而是隔一段时间后自动撤销回答"信号",不存在互锁关系。
所以请求信号的撤销动作会收到回答信号的制约,但是回答信号的撤销动作并不会受到请求信号的制约,因此这种方式称为半互锁方式。
全互锁方式
主设备发出"请求"信号后,必须待从设备"回答"后,才撤销"请求"信号。
从设备发出"回答"信号,必须待获知主设备"请求"信号已撤销后,再撤销其"回答"信号。双方存在互锁关系。
显然第一种不互锁方式速度最快,可靠性最差。第三种全互锁方式最可靠,但速度最慢。
这种异步定时方式优点是总线周期长度可变,能保证两个工作速度相差很大的部件或设备之间可靠地进行信息交换,目动适应时间的配合。
缺点:比同步控制方式稍复杂一些,由于需要等待回应,所以速度比同步定时方式慢。
半同步通信
是同步与异步结合。即在统一时钟的基础上,增加一个"等待"响应信号
如上图,比起同步定时方式,半同步通信方式会增加一个反馈信号
可以看出之前的同步定时方式每个总线传输周期都是定长的,是四个时钟周期。但是这种半同步通信结合异步通信方式优点,增加一个等待反馈信号,这样总线控制器可以根据这个反馈信号来动态调节传输周期种包含的时钟周期数。
分离式通信方式
具有上述三种通信方式共同点。结合刚才的例子,主设备要从从设备读出一个数据,那么主设备获得总线控制权后首先会发出地址和读命令,接下来从设备接收到命令后需要准备数据,数据准备好后才会通过数据总线给主设备发送数据。所以整个数据传输过程有三步:
这三个过程当中第一个过程需要使用到总线,第二个过程准备数据所以不需要使用总线。但这个时间段内这对主从设备依然会占据总线的使用权。最后一个阶段发送数据需要用到总线。所以优化的阶段是第二个阶段,当慢速的从设备在准备数据的时候,总线是空闲状态。所以分离式通信思想就是把总线的传输周期分离为两个独立的子周期:
子周期
子周期
所以这种分离式通信可以充分利用第二阶段准备数据时间,这个阶段把主线的使用权分配给其他设备使用,这样就能让总线传输效率更高。
这种方式特点:
常见的输入设备有鼠标和键盘。常见的输出设备有显示器和打印机。而硬盘和光盘是即可输入又可输出的设备。这些所有的
在总线那一章中介绍过单总线结构:
如上图外部设备通过
所以
上面
数据寄存器:存放主机要输出到外设数据,或者外设要输入回主机的数据。
控制寄存器:这个寄存器中存储的内容可以直接反映某一个外设具体要做什么动作,如键盘灯亮灭。
状态寄存器:反映了当前外设状态,比如说这个外设是否处于忙碌状态,是否损坏灯。CPU可以根据状态寄存器内部的标志位判断。
有以下代码:
xxxxxxxxxx
61int main(void){
2 char i;
3 scanf("&C",&i);
4 printf("i = %c\n",i);
5 return 0 ;
6}
了解这三个寄存器大致功能后CPU在处理scanf("&C",&i)
这段代码时,CPU会先通过控制总线向
程序查询方式
CPU不断轮询检查
如果状态寄存器现实已经完成,此字符数据会放在数据寄存器中,CPU可以通过数据总线取走数据寄存器中的值。
这种方式显然很低效,因为当读取
程序中断方式
程序中断方式:等待键盘
上面两种方式的数据流是:键盘
上面慢速设备用程序中断方式,向CPU发出中断请求次数较少,可以使用。但是一些快速的
为了让这些快速的外部设备与主机间的数据交互更有效率,一般采用DMA控制方式:
这是一种三总线结构,上面的DMA总线连接了DMA接口,这个DMA接口是专门由于管理高速的
DMA控制方式:主存与高速
DMA控制器自动控制磁盘与主存的数据读写,每完成一整块数据读写(如
DMA控制器与主存每次传送
因此引入DMA方式,如果此时有个某个程序需要进行数据读写,那么CPU会通过
这种DMA控制方式已经足够满足普通用户,但是对于商用中型机、大型机可能会接上超多的
通道是具有特殊功能的处理器,能对
CPU、主存和通道可以通过总线进行连接,如果此时CPU想要操作某一个
对于之前的DMA方式来说,只能连续读入或写出一整块数据,每传送完一整块的数据都需要CPU介入,而引入通道之后对数据的存取位置输入输出这些控制,可以通过通道指令变得灵活,只需要提前编址好通道指令程序即可。只有通道完成所有工作之后,才需要CPU介入一次。
一般来说,
CPU执行的指令。
操作码指明了CPU要对
通道指令:
通道执行的指令。通道程序提前编制好放在主存中。
在含有通道的计算机中,CPU执行
外部设备也称外围设备,是除了主机以外的、能直接或间接与计算机交换信息的装置。可以分为输入设备、输出设备和外存设备。
输入设备
用于向计算机系统输入命令和文本、数据等信息的部件。键盘和鼠标是最基本的输入设备。
输出设备
用于将计算机系统中的信息输出到计算机外部进行显示、交换等的部件。显示器和打印机是最基本的输出设备。
外存设备
是指除计算机内存及CPU缓存等以外的存储器。硬磁盘、光盘等是最基本的外存设备。
常见设备工作原理:
键盘
键盘是最常用的输入设备,通过它可发出命令或输入数据。每个键相当于一个开关,当按下键时,电信号连通;当松开键时,弹簧把键弹起,电信号断开。
键盘输入信息可分为
①查出按下的是哪个键。用硬件电路确定。
②将该键翻译成能被主机接收的编码,如ASCII码。
③将编码传送给主机。需要使用到
鼠标
鼠标是常用的定位输入设备,它把用户的操作与计算机屏幕上的位置信息相联系。常用的鼠标有机械式和光电式两种。
工作原理: 当鼠标在平面上移动时,其底部传感器把运动的方向和距离检测出来,从而控制光标做相应运动。
显示器
按显示设备所用的显示器件分类:阴极射线管(CRT) 显示器、液晶显示器(LCD)、LED显示器
按所显示的信息内容分类:字符显示器、图形显示器、图像显示器
性能指标:
屏幕大小:以对角线长度表示,常用的有
分辨率:所能表示的像素个数,屏幕上的每一个光点就是一个像素,以宽、高的像素的乘积表示,例如:
灰度级:灰度级是指黑白显示器中所显示的像素点的亮暗差别,在彩色显示器中则表现为颜色的不同,灰度级越多,图像层次越清楚逼真,典型的有
刷新率:光点只能保持极短的时间便会消失,为此必须在光点消失之前再重新扫描显示一遍,这个过程称为刷新。刷新频率是单位时间内扫描整个屏幕内容的次数,按照人的视觉生理,刷新频率大于
现实存储器(VRAM):也称刷新存储器,为了不断提高刷新图像的信号,必须把一帧图像信息存储在刷新存储器中。其存储容量由图像分辨率和灰度级决定,分辨率越高,灰度级越多,刷新存储器容量越大。VRAM容量计算公式如下:
考虑刷新率,一秒钟要往VRAM中写入
假如一个计算机分辨率为
注:现代计算机中,显存除了作为当前显示帧的缓存,还会用于保存即将渲染的图像数据,所以一般比容量最小值大很多倍。
如果是集成显卡计算机,通常分配一片内存作为显存。
阴极射线管(CRT)显示器
CRT显示器主要由电子枪、偏转线圈、荫罩、高压石墨电极和荧光粉涂层及玻璃外壳5部分组成。具有可视角度大、无坏点、色彩还原度高、色度均匀、可调节的多分辨率模式、响应时间极短等且前LCD已经超过。
液晶显示器(LCD)
原理:利用液晶的电光效应,由图像信号电压直接控制薄膜晶体管,再间接控制液晶分子的光学特性来实现图像的显示。 特点:体积小、重量轻、省电、无辐射、绿色环保、画面柔、不伤眼等。
LED(发光二极管)显示器
原理:通过控制半导体发光二极管进行显示,用来显示文字、图形、图像等各种信息。
LCD与LED是两种不同的显示技术,LCD是由液态晶体组成的显示屏,而LED则是由发光二极管组成的显示屏。与LCD相比,LED显示器在亮度、功耗、可视角度和刷新速率等方面都更具优势。
下面重点介绍CRT(阴极射线管)显示器。按照现实内容的不同可以分为一下几种:
字符显示器
显示字符的方法以点阵为基础。点阵是指由
现实字符原理:
上图的接口电路即
也就是上图右边的点阵信息,根据字符的ASCII码和CRT控制器信息选中某一个字符的字形码所存储的ROM存储单元,在这个单元中就存储了要显示字符的字形信息。之后把字形信息送到输出缓冲寄存器中,然后再通过另一个电路的控制把这个字符信息通过CRT将电子射向屏幕。最后屏幕会显示出该字符样子。这就是字符显示器显示字符原理。
注意:一个字大小是
图形显示器
将所显示图形的一组坐标点和绘图命令组成显示文件存放在缓冲存储器中,缓存中的显示文件传送给矢量(线段)产生器,产生相应的模拟电压,直接控制电子束在屏幕上的移动。为了在屏幕上保留持久稳定的图像,需要按一定的频率对屏幕进行反复刷新。
这种显示器的优点是分辨率高且显示的曲线平滑。目前高质量的图形显示器采用这种随机扫描方式。缺点是当显示复杂图形时,会有闪烁感。
对于图形显示来说按照扫描方式的不同可以分为光栅扫描显示器和随机扫描显示器。
这种图形显示器特点是显示图形不复杂很规则,如股票涨跌图。
图像显示器
就是电脑手机采用的显示器,可以显示丰富多彩图像信息。
还有一种常用输出设备是打印机,打印机是计算机的输出设备之一,用于将计算机处理结果打印在相关介质上。其按照印字原理不同可分为击打式打印机和非击打式打印机。
击打式打印机:利用机械动作使印字机构与色带和纸相撞而打印字符。如:机打发票、银行回执单(防伪性好)
击打式打印机优点是设备成本低、印字质量好。缺点是噪声大、速度慢。
非击打式打印机:采用电、磁、光、喷墨等物理、化学方法来印刷字符
非击打式打印机优点是速度快、噪声小。缺点是成本高。
按照打印机工作方式不同可分为:串行打印机:逐字打印、速度慢;行式打印机:逐行打印、速度快。
之前介绍过
通过之前的
可以知道
根据以上作用可以对
上图主机侧是内部接口与系统总线相连,实质上是与内存、CPU相连。数据的传输方式可能是串行也可能是并行传输。
设备侧是外部接口通过接口电缆与外设相连,外部接口的数据传输可能是串行方式,因此
图中右边有很多个外设界面控制逻辑,也就是说这样一个
发命令:发送命令字到
CPU连接在主机侧,外设连接在设备侧。CPU如果要操控打印机完成打印任务,首先CPU需要把打印机所对应的命令输入到控制寄存器当中。由于命令字千差万别,因此通常需要驱动程序协助。
读命令:从状态寄存器读取状态字,获得设备或
CPU从状态寄存器中读取状态字,同这种方式确认设备是否就绪,或者工作是否完成。
读
接下来CPU需要通过数据总线,往数据缓冲寄存器中写入想要打印的数据,之后在控制逻辑的控制下将这些要打印的数据逐个输出到打印机当中。打印机完成工作后就可以给
这里的CPU检查方式就是之前提到过的三种。
上图状态寄存器和控制寄存器写在一起原因是控制寄存器、状态寄存器在使用时间上是错开的,因此有的
注意:
上面的
接口与端口之间的关系如下:
接口包括端口和控制逻辑,其中端口又包含数据端口(用于读写)、控制端口(用于写)和状态端口(用于读)。
由于接口内部有多个端口多个寄存器,为了表明CPU要访问的是哪个寄存器,因此需要给这些寄存器进行编址。编址方式有两种:
统一编址
有称为存储器映射方式。统一编址是指
如上图内存占据
这种编址方式靠不同的地址码区分内存和
如系统总线中地址线共
优点:不需要专门的输入
缺点:端口占用了主存地址空间,使主存地址空间变小。外设寻址时间长(地址位数多,地址译码速度慢)。
独立编址
这种编址方式靠不同的指令区分内存和
优点:使用专用
缺点:
按数据传送方式可分为:并行接口、串行接口。
注:这里所说的数据传送方式指的是外设和接口一侧的传送方式,而在主机和接口一侧,数据总是并行传送的。接口要完成数据格式转换。
按主机访问
按功能选择的灵活性可分为:可编程接口、不可编程接口
之前介绍过
结合x86架构中的
指令格式 | 功能 |
---|---|
IN Rd, Rs | 把 |
OUT Rd, Rs | 把CPU寄存器Rs的数据输出到 |
由上图可以模拟打印
这种方式优点:接口设计简单、设备量少。 缺点:CPU在信息传送过程中要花费很多时间用于查询和等待,而且在一段时间内只能和一台外设交换信息,效率大大降低。
例题:在程序查询方式的输入
从时间角度计算
一个时钟周期为
鼠标:每秒查询鼠标耗时
硬盘:
每
最终查询硬盘耗时为
则查询硬盘所花费的时间比率
所以对硬盘的查询即使CPU将全部时间都用于对硬盘的查询也不能满足磁盘的传输要求。
从频率的角度计算
根据上面例题可以知道这种程序查询方式也可以采用这种定时查询,在保证数据不丢失的情况下,每隔一段时间CPU就查询一次
而之前所说的CPU会一直检查状态寄存器方式称为独占查询,这种独占查询就意味着CPU会花
程序中断是指在计算机执行现行程序的过程中,出现某些急需处理的异常情况或特殊请求,CPU暂时中止现行程序,而转去对这些异常情况或特殊请求进行处理,在处理完毕后CPU又自动返回到现行程序的断点处,继续执行原程序。
CPU响应处理中断基本流程是:
中断请求
中断源(鼠标、键盘等外设)向CPU发送中断请求信号。CPU在每个指令周期的末位都是例行检查是否有中断请求。
中断响应
响应中断的条件。如果检测到中断CPU会响应中断请求,首先会判断当前CPU自己的状态是否是可以响应中断的。如执行关中断指令后CPU就不会响应中断请求信号。
中断判优:多个中断源同时提出请求时通过中断判优逻辑响应一个中断源。如果CPU当前可以相应中断,就需要中断判优,即同一时刻如果有多个外设发出中断信号,CPU会判断执行中断信号的顺序。
中断处理
中断隐指令。将CPU的执行流
中断服务程序。修改PC值后就可以执行中断服务程序了。
上面介绍一个关中断指令,CPU检测当前是否处于关中断指令方法是可以将是否处于关中断状态的信息存放在PSW寄存器中,其在PSW中关中断指令的标志位是
所以如果当前指令的PSW中
如果此时CPU处于开中断状态,当检测到一个中断请求信号时判断这个中断请求信号是哪个设备发出的方法是可以设置一个中断请求标记。
这个中断请求标记寄存器是由一个一个触发器组成的。每个触发器记录一个二进制
CPU响应中断源必须满足三个条件:中断源有中断请求、CPU允许中断即开中断、一条指令执行完毕,且没有更紧迫的任务。
如果此时有多个外部设备发出中断信号,此时就需要中断判优操作。中断判优既可以用硬件实现,也可用软件实现:
硬件实现是通过硬件排队器实现的,它既可以设置在CPU中,也可以分散在各个中断源中
上图假设有多个设备的触发器是
上图最左边中断信号优先级最高,往右边越来越低。可以给多个中断信号进行优先级排序,优先级最高的会先执行。
软件实现是通过查询程序实现的。
需要判断触发器中每一位是否为
上面讲了如何判断优先级,而关于优先级设置定义如下:
上面对解决优先级问题后,还需要找到与中断信号相对应的中断服务程序去执行。也就是要找到中断服务程序的入口地址。即进入中断服务程序的方法是把该程序第一条指令的地址放入PC。之后处理完中断程序后,需要将PC的值恢复到执行之前指向的位置。所以在执行中断程序之前还需要保留PC的值。
保存PC值的工作可以交给中断隐指令。中断隐指令是保存原程序的PC值,并让PC指向中断服务程序的第一条指令。
中断隐指令具体任务:
关中断。在中断服务程序中,为了保护中断现场(即CPU主要寄存器中的内容)期间不被新的中断所打断,必须关中断,从而保证被中断的程序在中断服务程序执行完毕之后能接着正确地执行下去。
保存断点。为了保证在中断服务程序执行完毕后能正确地返回到原来的程序,必须将原来程序的断点(即程序计数器(PC)值的内容)保存起来。通常来说PC的值可以放到堆栈中,也可以存入指定的单元。
引出中断服务程序。引出中断服务程序的实质就是取出中断服务程序的入口地址并传送给程序计数器(PC)。
可以用两种方式确定中断程序入口地址:
软件查询法
硬件向量法
首先可以给每个中断请求信号进行编号。
如上图
整体工作过程是先线通过硬件排队器实现中断判优,中断判优会导致只有一个中断信号所对应的输出线会输出
上面向量地址还有一个别名叫中断类型号。用这种向量地址指向中断向量(入口地址)方式是因为,如果当某个入口地址发生改变只需要修改向量地址指向的中断向量值即可,不用修改硬件电路。
这里的中断隐指令其实并不是一条指令,指的是一系列的任务,而不是某一条指令。这些一系列的请求都是CPU检测到中断信号后一定会完成的指令。
现在找到中断程序入口地址后会执行中断程序。中断程序主要任务是:
保存原来程序的运行环境
保存通用寄存器和状态寄存器的内容(如:保存ACC寄存器的值),以便返回原程序后可以恢复CPU环境。可使用堆栈,也可以使用特定存储单元。
中断服务(设备服务)
主体部分,如通过程序控制需打印的字符代码送入打印机的缓冲存储器中(如:中断服务的过程中有可能修改ACC寄存器的值)
恢复环境
通过出栈指令或取数指令把之前保存的信息送回寄存器中(如:把原程序算到一般的ACC值恢复原样)
中断返回
弹出栈顶保存的程序断点信息,使PC回到源程序断点处。
中断处理过程总结:
上图关中断到开中断之间的指令不会被其他中断信号打断,知道最后执行开中断指令后才会响应中断请求信号。这种执行中断方式称为单重中断,即执行中断服务程序时不响应新的中断请求。
多重中断指的是当在执行某一个中断服务程序时,这个中断服务程序执行还有可能再次被中断。所以多重中断又称中断嵌套,执行中断服务程序时可响应新的中断请求。
实现多重中断当中断隐指令处理完保存断点和送中断向量一些列指令后,进入中断服务程序,此时在保护环境和屏蔽字后执行开中断,之后执行中断服务程序过程中就可以接受其他中断信号。最后再执行完中断服务程序后再次关中断恢复环境和屏蔽字。
这里把开中断指令放在保护环境和屏蔽字后面是为了主程序在执行保护指令时不被其他外设中断信号打断造成保存失败情况。同理,恢复环境和屏蔽字原理类似。
上图屏蔽字的全程叫做中断屏蔽字。其作用是给CPU指明哪些中断信号应该先执行。本质上也是在解决请求信号优先级的问题。之前的硬件排队器作用是当收到多个中断请求时,只响应其中一个固定优先级。可以调整这个硬件排队器使,增加中断屏蔽功能,这样硬件排队器可以更加灵活地调节各种中断之间的优先级。
这种中断屏蔽技术主要用于多重中断,CPU要具备多重中断的功能,须满足下列条件:
每个中断源都有一个屏蔽触发器,
屏蔽字设置的规律:
例题:设某机有
(1)写出每个中断源对应的屏蔽字。
由于
(2)按下图所示的时间轴给出的
当CPU在运行某个程序时,此程序需要用到用到外部设备输入。CPU会通过
例题:假定CPU主频为
设备D采用中断方式进行输入
若CPU需从D读取
主频
传送
传送
CPU用于完成
CPU用于该任务的时间大约为
在中断响应阶段CPU进行了哪些操作?
中断指令:关中断、保存断点(PC)、引出中断服务程序
DMA控制器通常是以块为单位进行读写的设备,如磁盘。
假设现在CPU要从磁盘中读入一整块的数据,采用DMA控制方式,CPU可以向DMA控制器指明要输入还是输出操作;要传送多少个数据;数据在主存、外设中的地址。接着由于数据的输入是要把磁盘一整块数据放入主存中,所以CPU需要给DMA控制器指明存放地址,此外CPU还要指明这些数据在磁盘中哪个位置。当CPU给DMA控制器发送完这些参数后,假设要输入的这一整块在磁盘中只占
接着对DMA控制器传送数据过程进行细化:
在对DMA控制器内部结构进行细化:
控制
DMA请求触发器:每当
主存地址计数器:简称AR,存放要交换数据的主存地址。
传送长度寄存器:简称WC,用来记录传送数据的长度,计数溢出时,数据即传送完毕,自动发中断请求信号。
数据缓冲寄存器:用于暂存每次传送的数据。
中断机构:当一个数据块传送完毕后触发中断机构,向CPU提出中断请求。DMA控制器完成一整块的数据传输之后,需要给CPU一个反馈,因此需要有一个中断机构发出中断请求信号。中断机构右侧连接了传送长度计数器,当传送长度计数器溢出后会给中断机构发送溢出信号。
注:在DMA传送过程中,DMA控制器将接管CPU的地址总线、数据总线和控制总线,CPU的主存控制信号被禁止使用。而当DMA传送结束后,将恢复CPU的一切权利并开始执行其操作。
DMA传送过程:
首先预处理阶段CPU会向DMA控制器指明接下来要读写的数据存放在主存当中的位置,主存地址寄存器指针是
接着进入由DMA控制器控制数据传送过程。此时对于CPU来说可以接着执行之前的程序。此时如果通过设备输入一个数据,设备首先要把数据送到数据缓冲寄存器中,同时向DMA控制器发送一个高电平信号。当控制
数据传送完成后,CPU受到中断请求就会进行后处理,也就是运行相应的中断程序,做DMA结束处理。最后CPU会回到主程序继续执行主程序。
相比于之前的程序中断方式来说,程序中断方式每一个字的传送都需要CPU进行处理。但是DMA控制方式意味着,会由DMA控制着传送完一整块的数据之后再通过CPU进行处理。DMA传送过程流程图如下:
上面讲述的方式DMA控制器需要经过CPU发送的信号来确定能不能使用系统总线,所以不会发生主存同时访问的问题。但是采用三总线结构:
可以看到主存和DMA控制器之间会专门用一个DMA总线进行交互,CPU和主存之间会专门用一根主存总线进行交互。在这种情况下DMA总线想要访问主存,就不需要通过CPU决定。所以这种三总线方式会出现CPU和DMA控制器同时访问主存的问题。如果这个主存不是双端口的主存,同一时刻只能支持一个访问请求,此时就产生访问问题。可以用以下三种方案解决CPU与DMA访存冲突问题:
停止CPU访问主存
DMA控制器传送一整块数据的过程,CPU不能使用主存。
这种方式控制简单,但CPU会处于不工作状态或保持状态未充分发挥CPU对主存的利用率。
采用DMA和CPU交替访存
主存的工作时间会被分为两段,红色段是
周期挪用(周期窃取)
DMA访问主存有可能会出现下面三种情况:
主存和DMA接口之间有一条直接数据通路。由于DMA方式传送数据不需要经过CPU,因此不必中断现行程序,
DMA方式具有下列特点:
DMA控制器方式与中断方式对比
中断 | DMA | |
---|---|---|
数据传送 | 需要通过程序控制完成数据传输 每次中断都会涉及到程序切换并且需要保存恢复环境 | 由硬件控制数据传输的过程 CPU只需进行预处理和后处理 |
中断请求 | 传送数据 | 后处理 |
响应 | 指令执行周期结束后响应中断 | 每个机器周期结束均可,总线空闲时即可响应DMA请求 |
场景 | CPU控制,低速设备 | DMA控制器控制,高速设备和块设备 |
优先级 | 优先级低于DMA | 优先级高于中断 |
异常处理 | 能处理异常事件 | 仅传送数据 |