[体系结构学习笔记2-1] 指令系统-数据表示
文章目录
前言
- 在机器上直接运行的程序是由指令组成的。
- 指令系统是软件与硬件之间的一个主要分界面,也是他们之间互相沟通的一座桥梁。
- 硬件设计人员采用各种手段实现指令系统,而软件设计人员则使用这些指令系统编制系统软件和应用软件,用这些软件来填补指令系统与人们习惯的使用方式之间的语义差距。
本章主要内容有三大方面:
- 数据表示
- 寻址技术
- 指令系统设计
有三种类型的指令系统:
- CISC:复杂指令系统
- RISC:精简指令系统
- VLIW:超长指令字
指令系统设计:
- 指令的格式设计
- 指令系统的功能设计
- 指令系统的性能评价
[2.1.1] 数据表示与数据类型
- 数据表示:指计算机硬件能够直接识别,可以被指令系统直接调用的那些数据类型
- 数据结构:串、队、栈、向量、阵列、链表、树、图等软件要处理的各种数据结构
数据结构要通过软件映像,变换成机器所具有的数据表示来实现
不同的数据表示可为数据结构的实现提供不同的支持
数据结构和数据表示实际上是软硬件的交界面,需要在系统结构设计时予以确定
底层数据表示的访存效率高
[2.1.2] 高级数据表示
自定义数据表示
- 标志符数据表示
- 一般的计算机中,数据存储单元(寄存器、主存储器、外存储器等)只存放纯数据,数据的属性通过指令中的操作码来解释(以下内容):
- 数据的类型
- 进位制
- 数据字长
- 寻址方式
- 数据的功能(地址、地址偏移量、数值)
- 同一种操作通常有多条指令
- 为缩短高级语言与机器语言之间的语义差距,可以让机器中的每个数据都加上类型标志位
- 一般的计算机中,数据存储单元(寄存器、主存储器、外存储器等)只存放纯数据,数据的属性通过指令中的操作码来解释(以下内容):
一个例子:
![](https://i-blog.csdnimg.cn/blog_migrate/812c26e7876bab03ea584df0081fccd9.png)
功能位:操作数、指令、地址、控制字
陷井位:由软件定义四种捕捉方式
封写位:指定数据是只读的还是可读可写
类型位:二进制,十进制,定点数,浮点数,复数,字符串,单精度,双精度;绝对地址、相对地址、变址地址、未连接地址等。
常规数据表示方法与带标志符数据表示方法的比较
![](https://i-blog.csdnimg.cn/blog_migrate/0c9558d7eb3a3aec818be97aa2821b9f.png)
上图中,红色为常规数据表示的指令与数据的关系(左至右的长度为字长);蓝色为使用标志符之后的
标志符的处理机所占用的存储空间通常要小
采用标志符数据表示方法的主要优点
- 简化了指令系统
- 由硬件实现一致性检查和数据类型转换
- 简化程序设计,缩小了人与计算机之间的语义差距
- 简化编译器,使高级语言与机器语言之间的语义差距大大缩短
- 支持数据库系统,一个软件不加修改就可适用于多种数据类型
- 方便软件调试,在每个数据中都有陷井位
采用标志符数据表示方法的主要缺点
- 数据和指令的长度可能不一致
- 指令的执行速度降低(但是缩短了设计、编译和调试时间,所以总体上快了)
- 硬件复杂度增加(把软件的难度挪到硬件)
自定义(Self-defining)数据表示
数据描述符
- 为进一步减少标志符所占用的存储空间,对向量、数据、记录等数据,由于元素属性相同,采用数据描述符
- 数据描述符与标志符的区别:标志符只作用于一个数据,而数据描述符要作用于一组数据(此描述符后面紧跟着一串数据)
一个帮助理解的例子:
![](https://i-blog.csdnimg.cn/blog_migrate/03355d1d350025be1cd16b9e7eceb2ed.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3d55156b010a1e6c4d95082ed53276c1.png)
![](https://i-blog.csdnimg.cn/blog_migrate/95c43f198d9fcb09753d9d8a5e75f8f0.png)
第一行的3表示有三个这样的数据(组)并且存了他们的起始地址(这一行是用来描述之后数据类型的(比如说三个单行数组));后三个101表示每一组数据有4个数据并且存了他们(数据)的起始地址(这几行是用来描述具体数据的(描述单行数组中的数据));后面就是顺序存放的数据
向量、数组数据表示
为向量、数组数据结构的实现和快速运算提供个更好的硬件支持的方法是增设数组数据表示,组成向量机(具有向量机了)
当然也就需要相对应的能处理向量数据的指令,之后对数据进行统一处理
![](https://i-blog.csdnimg.cn/blog_migrate/64f06a219b52efd73a884cc8a3aec46e.png)
向量指令能够把繁琐的单步操作整合起来(就是一次操作一组数据)
堆栈数据表示
堆栈数据结构在编译和子程序调用中很有用,为高效实现,很多机器都设置有堆栈数据表示
很少用嵌套程序来实现(一般数组实现寄存器来寻址)
堆栈的特点:
- 需要有高速寄存器(组)组成的硬件堆栈(堆栈堆,一系列的寄存器)
- 丰富的堆栈操作指令,功能强大
- 支持高级语言编译
- 支持子程序的嵌套和递归调用
[2.1.3] 引入数据表示的原则
- 看系统的效率是否显著提高,包括实现时间和存储空间是否显著减少
- 看引入这种数据表示后,其通用性和利用率是否提高
[2.1.4] 浮点数的表示方法
浮点数的表示方法
N = m × r m e N=m×r_m^e N=m×rme
两个数值:
- 尾数m:数制(小数或整数)和码制(原码或补码)
- 阶码e:整数, 移码(偏码、增码、余码)或补码
移码与补码有相同的表示能力(给定同样的机器字长,它们的表达范围相同)
两个基值:
- 尾数基值 r m r_m rm:2、4、8、16和10进制等
- 阶码基值 r e r_e re: 通常为2进制
这个基值意思是尾数和阶码是用什么进制来表示的
两个字长(有这两个长度占用物理位置):长度和物理位置,均不包括符号位
- 尾数长度p:尾数部分按基值计算的长度
- 阶码长度q:阶码部分的二进制位数
回忆原码补码反码移码:
以一个字节8bits来表示-3有:
[ − 3 ] 原 = 10000011 ; [ − 3 ] 反 = 11111100 ; [ − 3 ] 补 = 11111101 ; [ − 3 ] 移 = 01111101 [-3]_原=10000011;[-3]_反=11111100;[-3]_补=11111101;[-3]_移=01111101 [−3]原=10000011;[−3]反=11111100;[−3]补=11111101;[−3]移=01111101
尾数决定了浮点数的表示精度,阶值决定了浮点数的表示范围
![](https://i-blog.csdnimg.cn/blog_migrate/146bbfa05d0a8ea2e588f9f4115f012c.png)
小数点右侧都是尾数
非负阶、规格化、正尾数( r m r_m rm 为2的整数次幂时, r m m ′ = 2 m r_m^{m^{'} }=2^m rmm′=2m ):
- 可表示最小尾数(小数点后第1个 r m r_m rm 进制数位为1): r m − 1 r_m^{−1} rm−1
- 可表示最大尾数( $r_m $ 进制尾数均为 r m − 1 r_m−1 rm−1): ∑ i = 1 m ′ r m − i = 1 − r m − m ′ = 1 − 2 − m ∑_{i=1}^{m^′}r_m^{−i} =1−r_m^{−m^′ }=1−2^{−m} ∑i=1m′rm−i=1−rm−m′=1−2−m
- 最大阶值(阶值部分全为1): 2 p − 1 2^p−1 2p−1
- 可表示最小值: r m − 1 r_m^{−1} rm−1
- 可表示最大值: ( 1 − r m − m ′ ) × r m 2 p − 1 = r m 2 p − 1 × ( 1 − 2 − m ) (1−r_m^{−m^′ } )×r_m^{2^p−1 }=r_m^{2^p−1 }×(1−2^{−m} ) (1−rm−m′)×rm2p−1=rm2p−1×(1−2−m)
可表示数的范围:随着 r m r_m rm的增大,可表示最小值减小,可表示最大值增大,即可表示数的范围增大了
- 可表示尾数个数: r m m ′ − 1 ( r m − 1 ) = 2 m × ( r m − 1 ) r m r_m^{m^′−1} (r_m−1)=2^m×\frac{(r_m−1)}{r_m} rmm′−1(rm−1)=2m×rm(rm−1)
- 可表示阶的个数: 2 p 2^p 2p
- 可表示数的个数: 2 p r m m ′ − 1 ( r m − 1 ) = 2 p + m ( r m − 1 ) r m 2^p r_m^{m^′−1} (r_m−1)=2^{p+m} \frac{(r_m−1)}{r_m} 2prmm′−1(rm−1)=2p+mrm(rm−1)
可表示数的个数:随着 r m r_m rm的增大,可表示数的个数增大
一个例子:
( 1.75 ) 10 = 1.11 × 2 0 = 0.111 × 2 1 = 0.0111 × 2 2 (1.75)_{10}=1.11\times2^0=0.111\times2^1=0.0111\times2^2 (1.75)10=1.11×20=0.111×21=0.0111×22
当尾数不为0时,尾数域的最高有效位为1,这称为浮点数的规格化。否则,以修改阶码同时左右移动小数点位置的办法,使其成为规格化数的形式。
随着 r m r_m rm的增大,可表示最小值减小,可表示最大值增大,即可表示数的范围增大了
总结
尾数基值增大,会扩大浮点数表示范围,增加可表示数的个数,减少移位次数,降低右移造成的精度损失,提高运算速度,但也会降低数据的表示精度,数值的分布变稀疏
尾数下溢的处理方法
![](https://i-blog.csdnimg.cn/blog_migrate/9a2bb8144cce8242ff006f6ca4dd1209.jpeg)
因为字节位数的限制,一些特别大(绝对值)和小数点尾数特别多的数会表示不出来
- 截断法:将尾数超出机器字长的部分截去。优点是实现简单,不增加硬件,不需要处理时间;缺点是平均误差较大且无法调节
![]() |
![]() |
- 舍入法:在机器运算的规定字长之外增设一位附加位,存放溢出部分的最高位,每当进行尾数下溢处理时,将附加位加1。优点是实现简单,增加硬件很少,最大误差小,平均误差接近于零;缺点是处理速度慢,需要花费在附加位上加1以及因此产生的进位时间
![]() |
![]() |
- 恒置“1”法:把有效字长的最低一位置成rm/2。优点是实现简单,不需要增加硬件和处理时间,平均误差接近0;缺点是最大误差较大
![]() |
![]() |
- 查表舍入法:用ROM或者PLA存放下溢处理表。优点是速度快,平均误差可以调节到0;缺点是硬件量大
![]() |
![]() |
这个的具体实现比较复杂,给一个原理图帮助理解
![](https://i-blog.csdnimg.cn/blog_migrate/29748876d2ee921e15170f39e9cf1fba.png)
总结
![](https://i-blog.csdnimg.cn/blog_migrate/e4b35b3c0dca900c4f08b6bab871340a.png)
- 恒置法虽有少量的积累误差,且损失一位精度,但由于实现很容易,普遍在小型微型机中使用
- 舍入法只有少量积累误差,且精度比较高,但实现很复杂,用于软件实现的算法中
- 查表法实现比较容易,积累误差很小,且可以通过改变ROM或PLA中的内容来修正积累误差,是一种很有前途的舍入方法