title: 计算机系统概论-笔记
date: 2019-09-28 10:40:32
tags:
typora-copy-images-to: ./计算机系统概论-笔记
这是一本讲计算机组成原理和C语言的书.从最开始的与或非门,慢慢搭建出一个计算机的CPU来.从硬件开始明白,计算机是怎样工作的.
计算机是非常确定的系统,在相同的方法,相同的状态和起始条件下,同样的问题必然得到相同的结果
第一章 概述
基础理念
- 抽象 抽象可以使我们站在更高的层次来看问题.而看清事物本质,忽略其中细节,计算机的结构就是建立在一层一层的抽象上的.抽象使我们更有效率专注于特定的任务
- 学习组成原理时不要区分硬件和软件,硬件和软件是协同来工作的.互相影响并不是对立关系.硬件设备决定软件效率.软件也同样影响硬件.
- 只要有足够的时间和内存.所有计算机都能完成相同的计算任务,也就是所有计算机的处理功能是相同的.
- 人类通过语言来提问题,而计算机通过程序来解决任务.最重要的是人类语言描述转换为计算机程序的过程.
- 计算机的本质其实是数学和哲学问题.它认为任何问题都可以用数学描述出来.然后通过计算机计算出来.(这里就很神奇了.数学就相当于老子的道.一生三三生万物.同理用数学可以描述任何问题.而计算机只是用来计算这些数学问题的工具,难怪最开始都是数学家来参与制造计算机,他们是为了找到这种描述问题的数学规律,并设计出算法,然后用计算机表述出来.)
计算机的转换层次
问题要求描述清晰含义唯一.
算法 要求布操作步骤清晰,每步骤都能执行.最后可以终止(确定性,可计算性,有限性).
语言 要求是严格的顺序方式,让计算机执行.
机器指令集(isa)结构 是程序和计算机硬件沟通的接口的定义包括指令集合,操作数,数据类型,寻址类型.
微结构 是指令集具体功能的实现结构.指令相同.对应的微结构可能不同.每个处理器都有一个微结构
电路 微结构中就是一系列电路的排布组合.形成不同的逻辑电路
器件 就是最基础的电子元件了. 晶体管之类
总结
本章就是概括性的讲解了一下计算机的一些基本常识.和计算机能产生的深刻哲学理念和计算机组成的层次
第二章 bit 及运算
bit数据类型
电路中用1表示有电平,0表示无电平,这两个概念是相对的.
数据类型就是 数据的格式和对应的操作方法
整数数据类型 无符号整数其实就是正数.有符号整数则包括负数,这个表示有三种方法
表示有符号整数的方法
符号位表示法 把正整数的二进制的最高位(最左边未)1 表示负数,0表示正如 如 1001 =-1 0001=1
这种方式有两个0 0000=0 和1000=-0
反码表示法 把正整数的二进制按位取反 如 0101 =5 则 1010 =-5
这种方式有两个0 0000=0 和1111=-0
补码表示法 把正整数的反码在加1,表示对应的负整数 如 1011=11 取反为0100 补码为 0101=-11
0101+1011 =10000 最高位多出的1舍弃掉,保持原来的4位,则为0 也就是 -11+11 =0
这种方式只有一个0 0000=0
得到补码后, 两个数的减法就变成一个数和另一个数补码的加法,这样在硬件上容易实现.
- 因为采用补码进行加减法会很方便.因此计算机里都是对负数是使用补码的形式.
二进制十进制互转
以8位二进制为例,这里需要考虑二进制是正数还是负数,负数的话要拿到补码在计算,补码表示法中最高位代表符号位
十进制转二进制,就是每次除以2,记录余数,然后从右到左排列,得到二进制数.
bit运算
-
符号扩展: 二进制中,在正数前加 0 和在负数前加1都不会改变本身的值
如 5 = 000101 = 00000101 -5 = 111011 = 11111011
-
两个同符号二进制向加减,结果超过了最大值,就会造成符号溢出
如 5位2进制, 9(01001) +11(01011) =10100 结果的符号位成了负数(1),是因为超过了5位二进制的正数的最大数(01111),导致了溢出
-
逻辑与 AND
-
逻辑或 OR
-
逻辑非 NOT
异或 XOR 两个数不同的时候输出为真
这四个结构就是布尔代数的基础结构.也是很多电子原器件能时间的固定门结构
浮点数
浮点数用来表示小数.但也不是绝对的精确.只能在二进制数的范围内尽量接近结果.浮点数用固有的结构来表示,类似科学计数法,由三部分组成 比如 12340 =1.234*10^4
符号位:1bit 0为正数1位负数
数值范围:8bit 指数部分
数值精度:23bit 尾数部分
二进制十六进制互转
二进制的每四位都可以对应一个16进制, 因此直接四位四位一组转换就行
如 0011 1101 0110 1110 转换为 3 D 6 E 也就是3D6E
同理 十六进制转换二进制,就是把每位转成四个二进制01
总结
本章将了一些二进制的常用转换,其实最主要的是补码,通过补码把减法转换成加法,简化了计算机的实现.而浮点数则是通过牺牲数字的精度来扩大了数值的范围,包括表示更大的大数如 1.510^20和更小的小数.1.5*10^(-20)
第三章 数字逻辑
晶体管
n型 在栅极(g)加入电压,则源级d和漏级s之间联通逻辑门
非门的逻辑实现
in输入电压时,p断开n联通, out和ov相练.输出0v
in无电压时,p联通,n断开,out和2.9v相连,输出2.9v
电路in的输入和out的输出结果总是想反的
或非门
A B任一方有电压,都会导致上方p断开,下方0V联通, 则C输出为0v
A B都无电压时, 上方 2.9v 与C联通, 则C输出2.9V
或门
或门就是或非门的相反或者说 或门取反就是或非门
电路就是或非门的输出结构在加上之前的非门,把结果在反转
与门
左边部分.AB任意一个为0则上边两个P型会有一个连通,导致C输出为1,在经过非门后输出为0
A B 都为1时, 上边两个P行都端口,此时c输出为0,经过非门后为1
到这里二进制运算的与或非.就已经可以通过电路来实现了.而与或非,异或作为最基础的元件,在经过复杂的组合可以形成更多复杂的逻辑.下边把这几个门用符号抽象化,其中与非门和或非门就是对与门和或门取反
决策单元
决策单元是不能存储数据的电路组合,他的输出取决于当前的输入.输出后的数据也没办法在决策单元中存储起来.
简单来说决策单元就是由实时的输入产生实时的输出.并不保存结果.
译码器
所有的输出结果没次只有一个是1,其他都是零.这个几个结构用来检测匹配不同的输入模式.因为他可以通过输出的结果判断输入的来源
与门前的小圆圈表示对输入取反. AB的每种组合都对应一个输出线路.这就是一种判断逻辑
这是一个一拆多的组合
多路复用器
ABCD 一直是输入的数据源.有电压. 而通过S的两根线路的组合.来决定使用ABCD的那个输入来传递给输出.
这是一个多合一的组合
全加器
累加器是用来做二进制的加法的.二进制的加法 其实是三个输入产生两个输出的结果
如 a= 10111 加 b= 11101 其实是两个数的每一位逐渐相加.但是这里两个位相加可能会产生进位.所以应该改为是a和b的每一位和前一位产生的进位(可以是1或0) 进行相加. 产生的结果也包括当前位的和,和一个进位.用carryi表示第i-1位产生的进位, carryi+1表示i位产生的进位, si是当前位相加的结果 真值表如下
门电路如下,可以看到.两个1位相加,就需要这么多电路,然后产生的传ci+1还要作为下一位相加的输入进位.
讲多个1位的全加器组合,形成多为加法器
最右边的0 是第一位加法的进位,然后产生的c1作为第二位加法的进位. S0,S1,S2,S3则是每位加法后的结果,最后输出的二进制格式就是 C4S3S2S1S0
逻辑完备
指通过与或非三个门的各种组合,可以实现任何逻辑函数.类似道家的三生万物
存储单元
存储单元用来把数据保存在电路中,在使用的时候将其输出
R-S锁存器
他能存储1比特的信息,S和R是两个输入端 ab是输出端.这个器件规定RS不能同时为0.而且这个电路任何时候A和a相同,B和b相同.
这个器件的规律是.当S和R都为0或都为1时, a b的状态都是稳定不变
当R从 1->0时, a->0 b->1
当S从 1->0 是,a->1,b->0.
而 R或S从 0->1时 a,b的状态稳定不变
因此只有 R或S从1->0时,才会改变ab的状态,其他情况 ab保持不变, 这就相当于这个器件提供了保存状态的功能和变更状态的功能,这就是一个存储器.
门控D锁存器
在锁存器前在加两个控制,we表示可写,D是输入的数据,当we为0时,SR都是1.输出不变,只有当W0->1时,无论
D是0还是1.都导致 RS其中一个由1->0,就会导致其中一个输出会变为1
举例.We为1,如果D为0,R会 1->0,b变成1a变成0 We为1,如果D为1,S会 1->0, 则a变成1b变成0
因此 We为1时,a的结果和D同步,表示D的数据保存在了a中,we为0时,a的数据不会在变化.
到此.这个锁存器可以通过数据数据D和读写控制W来变更,保存数据了.
寄存器
把多个门控D锁存器相连,用同一个WE信号控制,就形成了多位的寄存器
下图是4位寄存器,D是数据源 Q是输出的存储结果 WE统一控制四位锁存器同时写入数据
内存
内存是由数量极大的存储空间构成,每个存储空间可以放一个数据.而每个数据我们可以约定他有8位或者4位或者16位锁存器组成. 这里的每个存储空间的识别符叫做地址. 而每个数据中含有的锁存器的个数(也就是能存储的bit的位数)叫做寻址能力.地址的总数叫做寻址空间.
以手机短信为例. 手机上最多装2000条短信,2000叫寻址空间.而每个短信可以包含100个字.就是寻址能力是100.
比如说电脑有16MB内存,表示该系统有16M的地址个数(寻址空间为16M),而每个地址的寻址能力是1字节(寻址能力是8bit)
时序电路
上文中,决策单元是不保存数据,当前的输出取决于当前的输入.存储单元是报错数据,可以持久使用.时序电路则是决策单元和存储单元的组合,既能存储数据,又能保存数据
时序电路的主要用于实现有限状态机.所谓有线状态机,就是指他有几个固定的状态,然后又固定的输入和输出,他会自己在这几个状态间切换,输入不同的状态.每个状态都会根据当前状态和当前输入来跳转到下一状态.例如红绿灯.红灯会在输入时间到变换时,根据现在是红灯状态,跳为绿灯,而绿灯则会跳到黄灯.
有限状态机表示一直逻辑上的顺序执行过程.他通过固定频率的市中电路来触发.
总结
本章讲了主要讲了最基础的与或非门器件,然后由这几个器件组成了计算机中最重要的决策单元和存储单元.这两部分就是计算机的核心部件.到这里我们就发现.计算机其实就是有一些器件进行封装组合,然后形成了控制逻辑,然后慢慢演化出了程序和数据.
第四章 冯.诺依曼模型
简单描述
内存
现在常用内存是 228-by-8-bit模式,也就是寻址空间为228(2^28个存储单元),寻址能力为8(每个单元容量为8bit)
访问内存需要先得到某存储单元的地址,放在CPU的内存地址寄存器(MAR)中,然后在发送读写信号,使内存和cpu的数据寄存器联通,数据从内存进入到数据寄存器(MDR)中.
处理单元
ALU是算数逻辑运算单元,可以进行加减法和与或非逻辑运算.ALU能处理的数据的长度成为字长,目前通常是32位和64位字长.
通常为ALU配置少量存储器.用来保存计算中间结果.因为从内存中读取太慢了.这些存储器叫寄存器,字长和ALU一直
输入输出单元
输入输出的读写速度更慢,通常会为他们分配缓存,CPU与缓存进行数据交流
控制单元
控制单元指挥其他单元协同工作.里边最重要的两个寄存器是指令寄存器,用来保存被执行的那条指令,程序技术器,保存下一条要执行的指令的地址.控制单元包括有限状态机,用来控制系统中的活动.
指令
冯诺依曼的核心思想是程序和数据都以bit流的方式存在计算机中内存中,程序在控制单元的控制下,依次完成指令的读取和执行.
-
指令是计算机执行的最小单元.由 操作码(要做什么)和操作数(对谁操作)组成.
指令的大概格式都是这样的. add r6 r2. 操作码 源操作数 目的操作数
指令周期
指令周期是指指令的执行步骤,指令在计算机控制单元的控制下一步一步执行,每个指令分为六个步骤,称为节拍,一个指令的完整执行过程叫指令周期.
取指令 FETCH
取指令就是把内存中某个指令,加载到控制单元的指令寄存器IR中.PC就是指向下一个要执行的指令的地址.详细步骤如下
把PC寄存器的内容装入MAR寄存器,该内容就是指令的地址
改地址对应的内容被装入MDR寄存器
控制单元江MDR寄存器的内容装入IR寄存器
PC寄存器的内容+1,指向下一个指令的地址
从这里可以看到CPU与内存打交道都是通过MAR,MDR寄存器, MAR保存某存储单元的地址,MDR从该单元拿到数据.而IR寄存器总是保存要执行的指令的内容,IP则总是指向下一个要执行的指令的地址.
这里的每个步骤都会花费一到多个时钟周期
译码 DECODE
译码操作是分析,检查指令的类型,并确定对应的操作.这里利用第三章的译码器 逻辑器件,确定指令对应的电路.
地址计算 ADDRESS
如果指令执行时存在地址操作,则在此节拍进行. 就是得到 指令操作数中完整的地址
取操作数 FETCH OPEAND
读取操作数地址对应的实际内容,这里也需要使用MAR装入上步计算出的地址,然后通过MDR把地址上的数据读取出来
执行 EXECUTE
指令已经识别出,操作数的内容也拿到了.这步就是执行指令.
存放结果 STORE RESULT
这是该指令周期的最后一个节拍,前一节拍的结果会被写入目的寄存器.该节拍完成后,控制单元再次从取指令开始执行下一个指令周期(因为此时PC寄存器已经指向下一个将要执行的指令地址了).这里就是一个有限状态机在不同状态的按顺序切换
改变指令周期
要想改变指令的执行顺序,比如跳到一个我们希望他执行的指令那里,例如循环时需要向前跳.就要在当前指令取指令节拍 后Pc指向下一个指令 到执行下一个指令的取指令节拍前,把pc执行的指令的地址改成我们希望执行的指令的地址. 这就需要用到控制指令, 控制指令就是在上文的执行节拍EXECUTE,主动修改PC寄存器的内容.那么本条指令执行完后,Pc就取出我们想要的指令的地址了.
停机操作
因为CPU是一条指令一条指令一直执行,如和才能停止运行呢,因为指令是根据CPU的时钟周期来运行的.意思是时钟不断发信号提醒指令执行不同的节拍,然后一直执行指令.因此想停掉指令执行,就是要停止时钟.也就是事运行控制位输出为0 .就停止了时钟.
总结
本章介绍了冯诺依曼的模型.现在的计算机都是采用这个模式来设计和组装的.这里边不同的硬件,对于CPU来说.都需要把数据读到寄存器中,CPU在从寄存器中读取使用.因为CPU的频率远远高于内存和io单元的频率.
接下来是指令执行的六个阶段.他是一种有限状态机.不停的在六个节拍中顺序执行.这里就用上了上章的译码器器件.
第五章 lc-3 结构
lc-3 是一个简化版的计算机.用来了解整个计算机的完整构造.
概览
内存
寻址空间是2^16(数据块),寻址能力是16位(数据块大小), 我们成这16位寻址能力叫做一个"字".
寄存器
内存和频率远远低于CPU的频率.CPU从内存直接读取数据就浪费大量时钟周期.所以CPU中有很多寄存器,其实就是告诉内存.他们和内存的原理一样,能存储数据,有唯一表示能独立寻址,用R0...R7表示8个寄存器
指令集
指令集包括 操作码(做什么)+操作数(对谁操作) 其实操作数中还包括 寻址模式, 也就是怎样定位到操作数的具体位置,该指令表示 把R0 和R2的值相加,结果保存在R1中
操作码主要分三类,运算,数据移动,控制. 运算指令负责处理信息(加减乘除与或非) 数据移动指令负责在内核和寄存器之间以及内存/寄存器和io设备间传递信息. 控制负责改变指令的执行顺序,如指令跳转.
全部指令如下 DR是 DestinationRegister目的寄存器 SR是SourceRegister 源寄存器 通常指令都是把sr的数据传入到dr中
寻址模式
是指定位操作数位置的方式.操作数通常在三个地方,内存,寄存器或数据本身.通过寻址模式和操作数的搭配确定操作数的具体地址. 寻址模式有5种,立即数,寄存器,相对寻址,间接寻址,基地址偏移
条件码
lc-3中有3个一位寄存器 N Z P ,当任何寄存器有数据写入时,根据结果,如果写入结果是负数,N为1.结果是0则Z为1,写入是正数则P是1. 这三个寄存器可提供信息给控制指令用来做条件跳转用.
操作指令
NOT
对源操作数按位取反,放入目的操作数 使用寄存器寻址模式,也就是源操作数和目的操作数都是寄存器
把 R5寄存器的值按位取反,结果放在R3寄存器中
ADD和AND
ADD是两个操作数执行补码加法.AND是两个操作数执行按位与. 这个指令需要2个源操作数,一个目的操作数.这里的源操作数,其中一个是寄存器寻址模式.另一个可以是立即数寻址模式或寄存器模式.
立即数就是把数值直接放在指令中作为源操作数.如 MOV AL, 0FH ; 将8位立即数0FH传送到AL寄存器中, 0FH就是立即数
下图是 把 R5和R4的结果相加.保存在R1中
数据搬移指令
搬移指令是在寄存器和内存/寄存器和Io间进行数据传输的指令. 数据从内存到寄存器叫装载(load),从寄存器到内存叫存储(store).
如果bit[9-11]是DR 表示把地址生成位中的数据加载到改DR中
如果bit[9-11]是SR,表示把该SR的数据保存到地址生成位的内存中
pc相对寻址
LD 加载指令 ST存储指令
该模式下 bit[0-8]表示的是相对位移.相对于当前pc计数器的位移,(上文说过pc计数器保存下一条要执行指令的地址) .pc相对寻址的限制就是 偏移量是针对PC的地址的.所以偏移的范围有限
如下图.此时pc的值是 x4019,相对x4019在偏移x1AF ,LD是加载指令.意思是把 (x4019+x1AF)地址中的数据保存到R2中
间接寻址
LDI 加载指令 STI存储指令
间接寻址中.地址生成位保存的是一个偏移地址A. 而A和PC相加后得到的数值是另外一个地址B.地址B的值才是最终要操作的内存地址.间接寻址可以使指令在更大的范围内跳转. 这是一种2次寻址.x
下图解释. pc当前的值是 x4A1C. 则偏移地址A =(x4A1C +x1CC)=x4BE8 ,下图写错了.应该是x4BE8的内容是x2110,然后在把x2110的内容放在R3中.
总结起来就是先进行一次pc相对寻址,再把得到的地址中的值交给R3
基地址偏移寻址
LDR 加载指令 STR存储指令
该模式先指定一个基地址寄存器.在指定一个偏移地址,最终的操作数地址由 基地址寄存器的值+偏移地址构成
下图解释, 操作数地址 = R2+x1D =x2345+x1D =x2362, 在把 x2362地址中的内容加载到 R1中
立即数寻址
LEA 将立即数与pc计数器地址相加.保存到另一个寄存器中.该命令用来对寄存器初始化.
立即数.这个词的命名意思就是,操作数就在指令中,直接就可以读取了(文中-3).就是立即得到.上图中,改指令读取指阶段,pc加1 变成 x4019, 执行时 x4019-3 =x4016. 再把x4016地址处的值复制给R5.
控制指令
控制指令可以改变指令的执行顺序.不用说.肯定是修改pc计数器的值.而且控制指令肯定是需要根据条件判断进行跳转.因此也用上了上边提到的 NZP 三个一位寄存器.
lc-3中有5中控制指令, 条件跳转,无条件跳转,子程序(函数).TRAP,中断返回
条件跳转指令
N negative 表示负数 Z zero 表示零 P positive 表示正数
bit[9-11]中的值如果与NZP三个位寄存器匹配时,该条件被触发.pc计数器就会计算pc计数器的值+pc偏移值, 也就是进行了指令的跳转.
在指令周期的执行节拍(EXECUTE),处理器检测bit[9-11]的条件码和 NZP三个位寄存器的匹配情况,如果匹配,就修改pc计数器的值.完成指令跳转.
上图中 pc=x4028 修改后的pc = x4028+x0D9 =x4101
如果 某指令的bit[9-11]位都设置为1. 则一定会触发跳转,这叫做无条件跳转指令.
jump指令
条件跳转指令的问题就是跳转是根据pc偏移值来跳转的.一共8位,跳转的范围有有限.而如果想在内存中更大范围跳转指令.需要使用jump
jump指令.使用源操作数的内容作为要跳转的地址,如下.表示要跳转到 寄存器R2的内容的地址上
trap 指令
trap指令和jump指令相似.都是改变pc计数器内容.跳转到新的指令执行地址.但是jump是在本程序中跳转.而trap则是直线操作系统控件内部,也就是跳转到操作系统的某个指令地址.这就是相当于开启调用系统服务api了.执行完成后.pc计数器会还原为原来本程序中trap指令的下一个地址,既接着执行本程序的逻辑.
数据通路
回顾一下上文的lc-3结构.下边进行介绍
全局总线
图中最粗最黑的先.lc-3的全局总线有16位,表示不同结构之间每次传递最多16位信息.同一时刻,总线只允许一个数据发送方发送数据.
内存
访问内存的步骤是.先将要访问内存的地址装入MAR寄存器,然后在看是读指令还是写指令.如果是load,会发送RD信号,把内存中数据送入MDR寄存器, 如果是store,则数据会放入MDR寄存器中,然后发送WE信号,使MDR寄存器中的数据保存至MAR寄存器指定的地址中. (感觉这里是硬件的执行逻辑了.是器材之间电路的联通)
ALU 和寄存器
ALU是算数逻辑单元,进行基础的运算. 接受两个输入,一个是寄存器.另一个是寄存器或者是立即数.ALU计算完成会把结果保存在通用寄存器中.同时改变三个条件码寄存器NPZ.
PC和PCMUX
pc计数器记录下一条要执行的操作.他会在指令周期的取指令节拍最后进行自增来指向下一条指令的地址.但同时上问介绍的控制指令.也是会改变pc计数器的值.因此有了PCMUX,PCMUX是一个三选一的多路复用器(第三章介绍过,多种输入数据,1个输出数据),PCMUX输入包括PC+1(正常执行)、利用offset计算的PC值(控制指令)、MDR(控制指令)
MARMUX
MARMUX是用来在load,store.trap指令执行期间,选择合适的地址输入.他会根据指令的操作码.来从他的几个输入地址中选择合适的地址.我的理解是他处理了各种不同寻址方式产生的结果.
IR寄存器
IR寄存器保存当前要执行的这个指令.当执行一条指令时,先把它从内存取到内存数据寄存器(MDR)中,然后再传送至IR
指令周期的案例
具体讲解,直接记录了,本指令开头是0110,对应指令格式如下 ,意思是把 baseR +offset6 地址的数据取出来.保存到DR中 DR =M[BaseR + offset6]
总结
本章主要分解了LC-3计算机的基础结构,分别是内存,寄存器,指令集,寻址模式,条件码..其中寄存器虽然有好几种,但本质都是存取数据的存储元件,只是保存不同的信息.而指令则分为操作指令(用于计算数据),数据搬移指令(用于移动数据)和控制指令(用于控制指令跳转),在加上三个位寄存器NPZ的配合,就实现了一部分逻辑功能,有点程序的感觉了.
接着是指令执行的一个周期中的6个节拍.每个节拍需要一到多个始终周期.而计算书就是根据时钟周期的信号频率还不断的运行.不同的节拍做什么,直接理解记住就好.这就是规则.
至于指令,其实操作码是主要的.反复就这集中,有的操作码还根据寻址模式不同,又多了几个变化,其实也是很好理解的
寻址模式是为了在不同程度上,在寄存器中的不同位置得到数据,这个也直接记录就可以.没难度
对于寄存器.概括就是 MAR记录内存的地址 MDR保存内存的值. PC指向下一个指令地址 IR保存要执行的指令
ZNP记录对寄存器数据变化的结果,用来做逻辑判断.
第七章 汇编语言
汇编语言是对机器指令的另一种表示方法.机器并不理解汇编语言.汇编语言最后也要翻译成机器指令.而汇编语言和机器指令的格式有点类似.每条汇编语言通常会对应一个机器指令.汇编语言需要经过汇编器汇编变成机器语言.
指令
LABEL OPCODE OPERANDS ; COMMENTS
操作码OPCODE 和操作数OPERANDS
这个和之前的机器指令是一样的. 操作码决定做什么.操作数决定对谁做.这里同样存在不同的寻址模式.
ru ADD R1 ,R3,#-1 把R3和 -1相加.结果在保存在R1中,这是立即数寻址方式
标号LABEL
指向内存单元的一个符号名.可以直接在内存中使用.用来做跳转或者做load/store用,其实是一种地址的简单表示方式如下 brp又跳转到了again标号的地方
注释 COMMENTS
注释用 ; 隔开,计算机不会别识别.是提供给人看的.
伪操作
伪操作并不会执行,是程序员传递给汇编器的信息.用来指导汇编器的汇编操作.汇编器看到这些信息,会把他们丢弃.
ORIG
告诉汇编器将lc-3程序放在内存的什么位置上.如 .ORIG x3050 表示程序从地址x3050出开始.
FILL
告诉汇编器将占用下一个地址,并填充数据 如 SIX .FILL x0006 对标号 SIX表示的单元填充 x0006这个值
BLKW
告诉汇编器将占用一连串的地址空间,用于分配数值不确定的空间 如 .BLKE 5 表示占用5个地址单元
其实这是一个申请内存的操作
STRINGZ
告诉汇编器将连续占用并初始化 n+1个控件为参数的字符+结尾符号 如 LABEL3 .STRINGZ "hello" 表示在Labe3 出占用6个连续控件, 存放 hello+结尾符号. 其实这就是字符串初始化操作.
END
表示程序结束
EXTERNAL
表示引用自本文件没有的符号,意思是多个文件进行汇编时, EXTERNAL 后标号label是定义在其他文件中的,需要把多个文件汇编在一起时把标号的内容绑定. 类型于java的import
汇编过程
汇编语言和机器语言的相似度是很高的 ,基本上每条汇编指令都能转化成机器指令,而汇编指令知识多了一些标号注释和伪操作,其中注释被忽略.而标号label和伪操作需要汇编器提前处理调.因此.汇编转机器语言需要两次扫描.第一次处理标号label及伪操作.生成符号表.第二遍逐句转化成机器指令.
第一遍 创建符号表
第一遍扫描时,逐行进行扫描,然后为每条指令和每个标号label分配地址,并记录标号和地址的对应关系,生成一个映射表.同时处理伪操作.
以下图程序为例
步骤如下,这个我觉得很容易理解了.就是逐行记录,lc计数器加一,然后生成记录表
第二遍 生成机器语言
这里遇到标号LABEL,会查第一遍生成的符号映射表,找到对应的地址,然后每生成一个指令,lc(地址跟踪计数器)就加一.这样每行指令的地址也就确定了.
总结
本章主要是讲解了汇编语言的基本格式.他格式同机器语言很像,只是多了一些提供给人看的方便理解的标号和注释及伪操作.注释完全是给人看的,而标号和伪操作则会在汇编语言转换成机器语言的时候,通过生成标号映射表及贵伪操作的执行给去掉.从而在机器语言执行的时候,只剩下了指令.
汇编时的两次扫描则是先生成映射表,在逐句生成机器指令.(这里只涉及单文件的汇编.多文件肯定还有些别的步骤和逻辑在)
第八章 输入输出
CPU与输入输出设备进行信息交流时,必须要通过寄存器及缓存.因为cpu的执行频率远远高于io设备.而且至少需要2个寄存器,一个用来和io设备进行数据交流.另一个寄存器保存io设备的状态,表示他当前是否空闲可以进行信息交流
基本概念
内存映射
内存映射指对于CPU来说,不区分是内存还是io设备,都把他们看作是内存.通过地址的方式来load或save数据.而io设备就需要把输入输出寄存器在内存中有一个地址标识.也就是io设备的寄存器被映射到一组地址上(这些地址就是分配给io设备的,而不是给内存分配的).这也就导致,CPU的寻址空间总数等于内存地址总数+io设备寄存器总数
异步io
异步io是指CPU和io设备的频率不同步二者是异步的.这里可以使用一个标志位,当io设备有数据时,该标志位为1.CPU把数据读取走后,该标志位置0.因为CPU的频率比io高.所以肯定是CPU会经常要查这个设备.一旦为1的时候就处理数据.而io设备则在自己有新数据的时候查一下.
中断驱动与轮询
中断驱动与轮询就是CPU和io设备交互的两种方式,区别在于双方谁控制这个交互.中断驱动是指io设备控制交互,他在有数据产生后主动通知CPU进行处理.轮询驱动则是CPU不断查询标志位是否是1.如果是1表示有数据从io设备产生.就要加载进cpu.(这里其实是说的输入设备,输出设备是把数据从CPU送到输出设备的寄存器.二者过程相反,原理相同)
键盘输入
键盘输入采取的是轮询的方式,也就是CPU不断查询标志位.那么键盘需要两个寄存器就够了 一个是KBSR(keyboard status register)键盘状态寄存器,1表示有输入0表示等待输入.一个是KBDR(keyboard data register)键盘数据寄存器,用来表示输入的数据.
当有数据输入时,键盘查询KBSR的状态,当为0时才把新输入的数据保存在KBDR中,并把KBSR置1.如果数据输入时KBSR为1,表示上一个输入还没处理完,则键盘无法继续输入.
CPU轮询查到KBSR状态为1时,把KBDR中的数据读取出来,然后把KBSR置0,表示数据被处理完
程序如下 BRZP 表示如果是0则跳转到Start继续轮询 BRnzp则是无条件跳转,表示及接受到输入数据,要进行数据处理了
显示器输出
显示器输出也是采用轮询方式,而且也是用两个寄存器控制,一个DDR(display data regist)用来接收展示的数据,一个DSR(display state register)用来表示数据展示状态
当显示器完成数据的展示后,把DSR置1,表示可以接收新的数据展示,此时CPU轮询后会把数据发送给DDR,同时把DSR置0,表示要显示器展示数据.
程序如下
中断驱动io
中断驱动就是iO设备控制交互状态,io设备发信号通知CPU获取数据,CPU不需要轮询.
io设备可以实现下列功能,1,强行停止当前程序2,让处理器处理io设备请求3,恢复之前停止的程序段执行,并好像什么也没发生过.中断既不改变原有程序的执行流程,也不改变原有程序的执行结果.
中断驱动就是 io设备插队了.他们执行完又恢复了原来的情况
中断驱动需要两个部分,1是产生中断信号,中止当前程序,2是处理中断请求.同时,中断的程序还要 比被中断的程序的优先级更高.
产生中断信号.
io设备的状态标识寄存器中,包含一位用来表示是否可以发送中断信号.这个标志位是由CPU设定给io设备的.如果该中断信号标志位为1.则当有输入输出数据产生时,会产生中断信号.
第15位是信号标识位 第14位是中断标识位
中断优先级
所有的计算机程序都有优先级别.只有中断程序的优先级高于被中断程序,中断才能发生.优先级高的开始执行,而优先级低的程序则挂起.等待中断程序执行完在继续执行.
中断检测
因为CPU不需要轮询,所以要有一种检测机制,让CPU知道发生了中断信号.这个步骤是在指令周期中完成的.
这就是在一条指令的末尾检测中断信号,有信号需要保存原来的信息,在执行新的指令,而原来的信息的保存方式就是用栈,在内存中用先进后出,把原来信息压入,再把中断程序也压入,当中断程序执行完后弹出栈,在弹出原来的状态信息,继续执行原来的程序.
总结
本章讲了CPU和io设备交互的两种方式,本质原因就是CPU的计算频率高于io设备的频率.因此需要采用异步的方式来交互.而异步的两种方式 轮询和中断,就是由谁来控制信息主导权的问题.不论哪种,都需要一个信号标志位表示数据产生了.中断还更复杂些
第九章 trap程序和子程序
trap程序和子程序是软件的两个重要部分,他们分别指调用系统的程序和调用自己或其他人封装的程序或函数,这是软件分层思想的一个具体实现.通过调用别人,可以使我们专注于自己要做的事.
TRAP程序
trap机制
tarp程序指调用系统程序,此时我们会把pc指向系统的程序,让操作系统来执行,执行完后在返回我们原来的程序继续执行.
TRAP机制包含以下要素:
服务程序 由操作系统提供,具有固定的起始地址,trap指令执行时,这写服务程序以用户的身份进行执行.
起始地址表 包含服务程序的起始地址和一组标号的映射关系,该表对用户程序公开
trap指令 用来从用户程序跳转到操作系统程序
连接 通过链接返回到用户程序,他是操作系统提供的由服务程序返回用户程序的机制.
trap指令
执行逻辑如下
要调用服务程序时把服务的标号装入MAR寄存器中,随后MDR中装入服务标号对应的服务的地址
当前PC寄存器的指令地址保存起来 保存至R7寄存器
pc计数器从MDR中读取服务其实地址,执行服务程序
最后通过链接机制返回用户程序,取出保存的指令地址继续执行
其实服务其实地址表的作用,有点像之前讲过的间接寻址,trap指令先指向服务地址表的某一项,然后这项数据在指向对应的服务的真实地址.
寄存器内容的保存和恢复
上文trap指令执行时,pc寄存器要先把trap指令的下一个位置的地址保存在R7寄存器中.然后服务程序执行完会把R7中的内容恢复至pc中.
这里的问题是,如果服务程序在巡行中使用了R7存储器怎么办?那么执行完成后肯定不能回到trap指令原来的下一个位置了.
因此这里设置一个原则,如果一个寄存器的原值要被其他方使用,那么你在使用他时需要将原值保存起来.修改完成后还要回复原值.这里有两个方式,调用者保存和被调用者保存.最好的原则是谁改动,谁保存.
子程序
子程序就是代码的复用,或者使用别人造好的轮子或sdk.
调用机制和trap机制类似,都是把子程序的地址装入PC,保存原来的下一条指令地址,子程序返回时,把下一条指令地址在写回PC.
JSR指令
用来从用户程序跳到别的用户程序,寻址模式有pc相对地址寻址,和基地址寻址.
改指令做两件事,把下一个指令地址存入寄存器R7,计算子程序的起始地址并装入PC
该指令分为两个 JSR是pc相对寻址 , JSRR是基地址寻址
意思是跳转到 PC+pcPffset11的地址去
意思是跳转到BaseR+bit[0-5]的地址去
总结
到这里.这两个指令就讲完了.这两个指令其实很类似.都是要保存原有指令的下一个指令的地址,然后读取服务程序或者子程序的地址,存入PC中,则下一个周期就是执行服务程序和子程序了.执行完成后,pc会把原来保存的指令地址在加载到pc中,这就实现了原来程序的继续执行,仿佛什么也没发生过
第十章 栈
基本结构
栈的基本原理就是先进后出(FILO),他是一种抽象的数据结构,有多中实现方式.
栈在内存中的实现,是通过一个栈顶指针.这个指针是一个寄存器,保存栈顶元素的地址,栈为空时栈顶指针保存栈的基地址的前一个地址.栈在内存中是从高地址向低地址增加,也就是有入栈时栈顶指针的值减小.最开始时,栈顶指针top保存的值是x4000,有新增元素后不断减一.弹出元素时top加一.
入栈
用R6寄存器表示栈顶指针,如下
ADD R6,R6,#-1 //R6减一,指针上移
STR R0,R6,#0 //把R0中值写入R6
出栈
LDR R0 ,R6 ,#0 //把R6指针的值保存在R0中
ADD R6, R6, #1 //R6指针下移
下溢出
弹出的值超过栈中的数量,empty 是基地址的前一个地址的补码,这里用empty和栈指针做加法,等于零,则表示栈指针指向了栈的基地址的前一个地址. 跳转的UNDERFLOW 是发生栈溢出时的处理程序的地址
上溢出
压入栈的值的数量超过了栈的容量.此时栈指针指向栈顶地址的上一个地址,MAX表示栈顶地址前一个地址的补码.与栈指针相加为0表示超过了栈顶 跳转的OVERFLOW是上溢出时的处理程序.
中断驱动
第八章讲了中断驱动,中断驱动是指io设备控制交互,io设备在有数据产生后主动通知CPU进行处理.此时CPU需要把正在处理的程序挂起,处理io的数据.处理完成后在恢复原来的程序处理过程.这里包括三个阶段
中断服务(io服务)的启动,中断服务的执行,中断服务的返回.
中断服务启动
中断服务(IO服务)通过发送INT信号通知启动中断,而在每个指令周期的最后节拍,CPU会查询INT信号,如果有则开始进行中断服务的启动阶段,包括保存当前程序的工资状态,装载中断服务,开始执行中断服务.
1.程序状态,指源程序的所有资源的快照.
包括改程序的内存空间和通用寄存器的内容,和PC寄存器和PSR寄存器,PC寄存器指向下一个要执行的命令的内存地址.PSR寄存器是处理器状态寄存器,包含改程序的相关信息,如PSR[15]表示运行模式(超级用户还是用户),PSR[10-8]表示程序优先级,PSR[1-0]表示nzp
2.被中断程序的状态保存
保存原程序的状态,使中断程序结束后原程序继续执行,这里要把源程序的PC寄存器的值和PSE寄存器的值.这些数据保存在由一个超级用户栈(个人理解就是操作系统控制的栈),这个栈与用户的栈隔离,
中断服务执行
1.中断程序装入
和trap指令类似,也是先把中断服务的标号保存进寄存器,在读取标号对应的中断程序的地址,在加载该地址.
pc计数器读取中断程序的真实地址,同时PSR寄存装入中断进程的相关信息.
2.中断程序开始执行
中断服务返回
中断程序最后是RTI指令,改指令使超级用户栈中的PC和PSR值弹出,回归到处理器的正确位置
pc寄存器就开始执行源程序的下一个指令.
总结
中断和tarp指令比较像,就是这里使用了超级用户的栈来保存之前的信息,从而实现两个程序的切换,在中断程序完成后,在恢复原来的程序的数据