计算机组成原理
计算机是如何工作的
| 认识计算机中的基本部件 | PC:程序计数器; |
| ---- | ---- | ---- |
| CPU:中央处理器; | MAR:存储器地址寄存器 |
|ALU:算术逻辑部件;|IR:指令寄存器;|
|MDR:存储器数据寄存器|GPRs:通用寄存器组(由若干通用寄存器组成,早期就是累加器)|
CPU:中央处理器; PC:程序计数器;
MAR:存储器地址寄存器 ALU:算术逻辑部件;
IR:指令寄存器; MDR:存储器数据寄存器
GPRs:通用寄存器组(由若干通用寄存器组成,早期就是累加器)
-
做菜之前
原材料,菜谱,架子,编号
原材料和菜谱都按照顺序放在架子上并且有一定的编号
原材料(数据)和菜谱(指令)都按照顺序放在架子(储存器)上并且有一定的编号(储存单元地址)
(菜谱的内容是包含原材料的位置,做法,做好了放在哪里)
-
开始做菜
第一步:从五号架子上面去菜谱(CPU 根据PC取指令)
第二步:查看菜谱(指令译码)
第三步:根据菜谱从何处取出原材料(根据指令取出操作数)
第四步:洗切炒具体操作(计算机在ALU上面进行具体操作,与,或,非)
第五步:装盘或者是直接送桌(回写出结果)
第六步:算出下一个菜谱所在的架子号6 = 5+1(修改PC的值)
-
程序在执行之前
数据和指令事先存放在存储器中,每条指令和每个数据都有地址,指令按序存放,指令由OP、ADDR(OP是操作字段,ADDR是地址字段)字段组成,程序起始地址置PC(原材料和菜谱都放在厨房外的架子上,每个架子有编号。妈妈从第5个架上指定菜谱开始做)
-
开始执行程序
第一步∶根据PC取指令(从5号架上取菜谱)
第二步∶指令译码(看菜谱)
第三步:取操作数(从架上或盘中取原材料)
第四步:指令执行(洗、切、炒等具体操作)
第五步:回写结果(装盘或直接送桌)
第六步:修改PC的值(算出下一菜谱所在架子号6=5+1)
继续执行下一条指令(继续做下一道菜)
计算机的指令中需要给出的信息
操作性质(操作码)
源操作数1,(源操作数2)
目的操作数地址
原码和移码的表示
-
什么是移码表示?
将每一个数值将上一个偏置常数(Excess/ bias)
通常,当编码位数为n的时候,bias取
-
机器里面的移码表示也就是编码表示
-
为什么使用移码来表示指数(阶码)?
-
便于浮点数加减运算时对阶的操作(比较大小)
-
小栗子:
取的运算的位数为3,所以移码是2的3-1次方等于4
-
运算器的模运算
补码的定义
X是真值,[x]补是机器数
在32位机器中:
int中机器数的位数是32位
char中的机器数的位数是8位
short的机器鼠的位数是16位
负数的补码应该怎么求:各位取反,末尾加一
如何求补码的真值
简便的算法:
符号为0,则为正数,数值部分相同
符号为1,则为负数,各位取反末尾加一;数值从右向左遇到第一个1不变,然后各位取反
C语言里面的数值表示
C语言里面的整数
- 无符号数和带符号数运算的时候都按照无符号数来运算
- 在c90和c99里面的符号数 和 无符号数的判断界限不一样,因此同一可能会产生不同的结果。
C语言里面的浮点数(IEEE754标准)
实数分为:单精度,双精度,扩展双精度 float double longdouble
C语言里面的科学计数法与浮点数
使用科学计数发,但是只有一种的是规格化的表示。
对于十进制的小数,可以使用科学计数法,同样的,对于二进制的小数也可以使用科学计数法:
对于浮点数的表示方法:
由于规格化表示的原因,小数点之后的数字第一个总是1,所以省去这一位的表达,所以实现了使用23位表示24位的方法
- s是符号位
- E是阶码,通常使用移码(加上
)来表示
- 尾数规格化显示的定义是第一个数字为1,所以舍弃不予以显示。
32位浮点表示规格化数的表示范围。详见csapp
非数值数据的编码表示
-
西文字符的编码表示:
需要掌握基本的字母和数字的ASCII码表
-
汉字的编码表示:
- 输入码:对汉子用相应的按键进行编码表示
- 内码:用于在系统中进行存储,查找,传送等处理
- 字模点阵或轮廓描述表述汉字字模点阵或轮廓,用于显示/打印
数据宽度和存储量位的单位
-
比特:(bit)位,是计算机处理,储存,运输的最小单位。
-
字节:二进制信息最基本的计量单位是”字节“Byte
- 一个二进制的Byte是8位
- 现代计算机中的储存器都是按照字节编址
- 字节是最小的可寻址单位
- 如果字节排列,LSB是最低有效字节 Msb是最高的有效字节
-
字和字长:经常使用“字”作为单位
- 字和字长的概念不同。字是结构决定的
- 字长是数据通路的宽度
-
容量通常使用的单位有
- KB,MB,GB,TB
-
通信中的带宽使用的单位有
- kb/s 1kbs = 1000bps
- Mb/s 1Mbps = 1000kbps
- Gb/s 1Gbs = 1000Mbps
- Tb/s 1Tbs = 1000Gbps
如果把b换成B表示的是字节而不是比特(位)
高级语言支持不同的类型和不同的长度的数据,而且相同类型的数据采用的宽度也不尽相同。
数据储存和排列的顺序
-
存储的字节数:一个数据可能会占用多少个存储单元
-
地址存放:变量的地址是最大地址还是最小地址
-
大端/小端存放:多个字节在存储单元中存放的顺序如何
-
小端方式:LSB 所在的地址是数据的最小地址
-
大端方式:MSB所在的地址是数据的最小地址
例如:一个int数据,占用了32位4的字节,把这四个字节分别记作100,101,102,103
在同一个系统之中,大端和小端是一定的,但是在网络交互通信的时候,就需要做相应的更改。
-
逻辑“与或非” 和 电路之间的关系
或电路:
与电路:
非电路:
通过与或非的电路可以构建多有的电路逻辑
异或电路:
异或电路就可以使用这三种电路来进行构建
异或电路的简单表达方式
根据电路是否有存储的功能可以分为两种
- 组合逻辑电路:没有存储功能,其输出仅依赖与当前输出
- 时序逻辑电路:具有存储功能,其输出不仅依赖与当前输出,还依赖于存储单元的当前状态
可以利用基本的逻辑门电路构成一些具有特定功能的组合逻辑部件
- 译码器,编码器,多路选择器,加法器
实现一个功能部件的过程
- 得出真值表
- 通过真值表来确定逻辑表达式
- 根据逻辑表达式实现逻辑电路
加法器的实现
n位加法器可以通过n个加法器实现。
计算机的比较运算和减法运算
计算机的比较运算是通过减法运算组成的,但是计算机的所有运算都可以通过加法运算来构成。
带标志的加法器。
n位整数的加、减运算器
-
在一个int运算里面,机器数表示都是补码运算
-
补码的运算公式:
-
因此在机器里面int的加减运算就可以表示为
-
各位取反,末尾加一:
-
-
在加减运算的公式下面可以得到如下结论
- 利用带标志的加法运算器,可以构造出整数加减的运算器(带不带符号都可以)
- 为什么sub为1的时候做减法-------------------------------->各位取反,末尾加一
- sub作为2路控制器的同时,担任了加法器cin进位,十分巧妙。
ALU的基础就是n位正数的加减运算
- 核心电路:带标志的加法器
- 基本的算术运算与逻辑运算
- 加减运算(带符号,不带符号)
- 以,或,非,异或等逻辑电路
- 多种操作,但是如何判断结果的操作方法-—–>操作控制端
- ALUop是操作控制端,用来决定ALU所执行的处理功能,他的位数K 军定了操作的种类,例如k为3的时候,就可以有最多2^3 = 8中操作
计算机是实现高级语言程序中的运算
-
将表达式编译为指令序列
-
计算机直接执行指令来完成运算
- 控制器对指令进行姨妈,产生控制信号送到运算电路
-
操作数在运算电路中运算
数据的运算都是由逻辑门运算产生的。
高级程序运算-----》指令运算-----》电路运算
- 两次转换----电路到指令---指令到电路。
C语言中涉及到的运算
-
算术运算
- 加减乘除,浮点运算,有无符号的运算
-
按位运算
- 按位与, 按位或,按位取反,按位异或,吸取操作。
- 吸取操作
-
移位运算
- 扩大或缩小2,4,8…倍数。
- 逻辑移位
- 移位溢出:高位溢出的是1,则左移溢出
- 左移:高位移出,低位补零
- 右移:低位移出,高位补零
- 算术移位
- 移位溢出:移出前和移出后的符号为是否相等
- 左移:高位移出,低位补零
- 右移:低位移出,高位补零,可能会发生有效数据丢失。
-
逻辑运算
- 用于关系表达式的运算,例如 if,and ,else等
-
位扩展和位截断运算
-
类型转换的时候使用到的,没有默认的运算符。
-
例如在类型转换的时候,长的数据类型转化成短的数据类型是位截断运算,短的转为长的是位扩展运算
-
扩展运算:有符号数扩展符号位,无符号数扩展0
-
截断运算:截断前面多余的位数。
-
-
C语言中加减运算器的实现
-
重要认识1:计算器中所有的运算电路的实现核心
-
重要认识2:加法器不知道运算的带符号数还是无符号数
-
重要认识3:加法器不喷段错,总是去低n位做结果,并产生标志信息
加法运算器的具体实现
标志寄存器的标志信息
-
ZF零标志:如SUM 为0的时候,ZF为1
-
OF溢出标志:若两个加数同号但是SUM不同号则1;次高位进位和最高位进位进行异或
-
SF:表示sum的符号
-
CF:表示借位或是进位。
做减法以比较大小,规则:
Unsigned:CF=0时,大于
Signed:OF=SF时,大于
C语言中乘运算
如何判断乘法运算是否溢出
-
高级语言里面,程序员直接使用(!x|x*y/x == y)判断即可
-
带符号运算:如果高位的数字和低n位的最高位相同的时候,没有发生溢出
-
无符号运算:如果高n位全为0,那么没有发生溢出。
因此带符号乘和无符号乘是使用不同的指令进行的。
但是带符号加和带符号减是相同的指令进行的
- 证书的乘法运算时间 大于 整数的加法和移位运算时间长,因此一次乘法运算可以分解为移位运算和加运算、
除数的除运算
”朝零舍入“ 7/2 = 3 -7/3 = -3
a/-1和a/b,b=-1不一样,前者可以被优化为取负运算。
- 取负指令的运算比较法咋,不能通过流水线的方式实现,一次处罚的运算时间大致需要30个时间钟
- 不能乘除的情况
- 注意带符号数的运算方式,因为带符号数的运算需要先加上一个偏移量,然后在进行截断
- 注意:k是运算时的右移位数
C语言浮点数的运算
-
加减运算
-
再阶码的运算当中要“对阶”,也就是低阶向高阶转化
-
规格化:当位数高位为0的时候有进位,需要左规MSB为1
当位数高位有进位的时候,需要右规直到MSB为1
-
-
乘除运算
-
阶码上溢
-
阶码下溢
-
为了防止数据的溢出,硬件会设置一些附加位以调高精度。IEEE754规定至少有两位,一位是保护位,一位是舍入位。
C语言的舍入方式
- 就近舍入:舍入为最近可表示的数
- 01:舍弃
- 11:进位
- 10:强迫结果为正数
- 正向舍入
浮点数运算是发生的错误
- 除数为0的时候,得出的结果是无穷大,阶码位全是1,位数全为0符号位为0或1
- 浮点数的结合率是不符合的
机器极指令
-
机器指令和汇编指令是一一对应的,都是机器级指令。
-
机器指令是一个01序列,由若干个字段组成。
-
汇编指令是机器指令的符号表示(有不同的格式)
-
回顾一下GCC套件的执行顺序
- == 预处理、编译、汇编、链接 ==
-
使用objdump反汇编代码的时候,机器数的地址不是实际的地址,是从0开始的地址。
-
他的长度是使用十六进制进行的
-
回顾一下ISA(指令集体系结构)
- ISA 是计算机中硬件的抽象,是一种软件和硬件之间的接口。
所有指令的格式,功能
通用寄存器的个数,位数,编号和功能
储存地址空间大小,编址方式,大、小端
指令寻址方式
Intel的体系结构概述
- 拥有八个通用寄存器GPRs和一个标志寄存器(通用寄存器都是成组出现的)
- 拥有一个PC 为EIP的计时器
- 可寻址的空间是4G 232 个字节,其他的指令都是可变长的
-
IA-32的寄存器的组织概览
-
各个位数寄存器编号0~8
-
3个控制标志
-
df if tf
- 方向标志(自动变址方向)
- 中断允许标志(仅对外不可屏蔽的中断有效)
- 陷阱标志(是否单步跟踪状态)
IA32的寻址方式
-
寻址方式:
- 如何根据指令得到操作数的地址或操作数
-
操作数所在的位置
- 指令中 :立即寻址
- 寄存器中:寄存器寻址
- 存储单元中:其它寻址方式
-
储存器的操作数的寻址方式分为两种
-
实地址模式(用不到)
-
保护模式(掌握)
-
加电以后采用虚拟储存管理,多任务情况下隔离保护
-
寻址空间为 232B,32位线性地址
-
寻址方式十分复杂,这与寄存器的数据结构有关系。
-
储存器的寻址方式(SIB)
按照一个C语言的变量声明说明声明方式:
windows里面double分配的地址必须是8的倍数。所以c以后空了一行多。
-
操作指令 操作长度, 基质(基址寄存器(%ebp) + 变址寄存器(%esi)+ 比例因子 ),移动目标
一个地址就是一个字节byte就是四个比特(b)就是4位。
IA-32常用的指令类型
例如数组a[i] [j]的寻址方式是需要基址寄存器和变址寄存器和比例因子。
机器指令格式的概览:
其他的指令类型太过于复杂,不做记忆要求。
- 传送常用运算常用指令
- 定点算术运算指令
ALU里面都有什么东西
- 补码运算
- 实现带符号运算
- 实现无符号运算
- 没有乘法运算器(可以使用加法运算器实现)
- 没有除法运算器
- 逻辑门的运算
IA-32 运算指令
- 加法运算指令
- 乘法运算指令
- 按位运算指令
- 控制转移指令
……
C语言函数过程调用的机器级表示
过程调用的执行步骤:
- 调用函数将入口参数(实参)放到被调用函数能访问到的地方
- 调用函数预先保存返回地址(压栈),单后将控制转移到被调用函数
- 被调用函数保存调用函数的现场(main函数通用寄存器的内容??),并且为自己的非静态局部变量分配空间
- 执行被调用函数
- 被调用函数恢复调用函数的现场,释放局部变量空间
- 取出返回地址,控制权转移给调用函数。
为什么要保存现场?
因为所有的过程都共享用一套通用寄存器。
关于寄存器使用的约定
-
调用者P保存寄存器 : EAX,EDX,ECX
Q可以直接使用这三个寄存器
若P在从Q返回后还要用的话,P应在转到Q之前先保存,并凑单从Q返回后先回复他们的值再使用。
-
被调用者Q保存寄存器:EBX ESI ,EDI
Q必须先将它们的只保存到栈中再使用他们,并在返回P之前恢复他们的值
-
EBP 和ESP分别是 帧指针寄存器和栈指针寄存器,分别用来指向当前栈帧的底部和顶部。
为了减少准备和结束阶段的开销,每个过程应先适用哪些寄存器? 调用者的寄存器