本文为读书笔记,是对书中自己认为重要的点进行简要摘录和总结,如需要更进一步了解,还是推荐看原书,作者讲的非常详细。
原书:郑钢 操作系统真象还原
文章目录
1:cpu8086实模式
1.1:cpu工作原理
大体分为三个部分:
-
控制单元:由指令寄存器(IR),指令译码器(ID),操作控制器(OC)组成,
- 操作控制器OC给运算单元下命令
- IR通过IP寄存器的指向,将内存中的指令放入IR中
- ID按照IA32指令格式将指令解码:分析出操作码是什么,操作数在哪里等
-
运算单元:算术运算(加减乘除)和逻辑运算(比较、移位),命令从控制单元
-
存储单元:CPU 内部的 L1 、 L2 缓存及寄存器,待处理的数据存放地。为什么数据已经在内存中还要重复存储呢?由于内存的存储器称为DRAM
动态随机访问内存(DRAM)即插在主板上的内存条,动态就是指此种存储介质由于本身电气元件的性质,需要定期地刷新。内存条这么小却要装下这么多的电容,导致电容容易漏电,因此需要定期的补充电量来维持内存数据不丢失
而SRAM(静态存储器)不需要刷新电路即能保存它内部存储的数据,其中包含了程序员可见和不可见的寄存器,所以这是为了保证指令操作数的完整性。
(图中如取指令和得到指令是一个过程,其他类似)
执行指令过程
- 读取下一条指令:读取cs:ip地址(x86中在程序计数器PC中)-> 送上地址总线、获得指令 -> 存入指令寄存器中
- 译码:译码器ID根据指令格式检查IR中指令 -> 确定操作码和操作数类型
- 取操作数:根据操作数类型-> 操作数在SRAM的寄存器中直接可以用 ->在内存中即需要内存寻址则通过地址总线将操作数放入SRAM
- 运算:OC给运算单元下令开工
- 更新ip:ip = ip + 当前指令的长度,若跨段,还要更新CS
1.2:实模式下寄存器
CPU寄存器分两大类:
一类是内部使用的,对程序员不可见,是给CPU内部的数据提供存储空间,如GDTR,LDTR,TR,CR0~3,IP等
一类是对程序员可见的寄存器。
16位cpu的8086有14个16位寄存器,这14个寄存器按其用途可分为
(1)通用寄存器 (2)段寄存器 (3)标志寄存器 (4)指针寄存器等4类。
通用寄存器
指针寄存器和变址寄存器,包括:
-
SP(Stack Pointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置,常为栈顶
-
BP(Base Pointer):基址寄存器,可用作SS的一个相对基址位置;
-
SI(Source Index):源变址寄存器,与DS段基址搭配,作为偏移量
-
DI(Destination Index):目的变址寄存器,与ES段基址搭配,作为偏移量
段寄存器
值得说明的是在 16 位 CPU 中,只有一个附加段寄存器一ES。而 FS 和 GS 附加段寄存器是在 32 位 CPU 中增加的。我们使用的是 32 位 CPU,并不是说 32 位 CPU 在实模式下的 16 位环境中就不能用 FS 和 GS 寄存器。 (32 位的 CPU 兼容 16 位 CPU 的特性)
标志寄存器
16位实模式下称为flags,是记录一些产生运算结果的过程。标志位常用来作为判断的条件,本质上是上一条指令执行的结果,如进位、位溢出、结果为零等等。
指针寄存器
IP寄存器是不可见寄存器,而CS寄存器是可见的,cs 寄存器用来存代码段段基址, IP寄存器用来存储代码段段内偏移地址。
CPU取指令的地址就是通过CS:IP获取的,读取完一个指令后,把当前IP+已读完的指令长度之和作为新的IP值存入指针寄存器,如果这个指令还是一个跳转指令,CS也会更新。
1.3:实模式下CPU的内存寻址方式
内存寻址是寻找“数”的地址,这个“数”可以源操作数,也可以是目的操作数。
大方向上分三类
- 寄存器寻址:“数”在寄存器中
- 立即数寻址:“数”是常数,由于找数不需要花费cpu运行周期,能够立即拿来用
- 内存寻址:内存寻址遵循一个大前提:采用“段基址:偏内偏移地址”的形式。
- 直接寻址:”数“所在的内存地址是是立即数,默认段地址是DS。
- 基址寻址:操作数用bx或者bp作为偏移地址,ss:bp访问栈中元素
- 变址寻址:使用si或者di变址寄存器
- 基址变址寻址:同时使用基址和变址寄存器,如ds:bx+di形式
1.4:栈
栈是线性表的一种,线性表是有线性性质的表,也就是连续的(不是地址上的连续),并且任意位置只有一个元素的表结构,栈作为特殊的一类,只能从一端入栈,另一端作为存储单元的基址永远不动
数据结构的栈是逻辑上的,而物理上的栈存储在内存区域中,和数据段意义一样,通过SS和SP来访问栈中元素。
栈顶指针(SP):作为栈的出口和入口,一般通过push和pop指令可以改变其指向,栈扩栈的方向是从高地址向低地址,入栈—SP减去新元素的字长。但是栈中访问内存还是从低地址向高地址的
1.5:ret,call
ret:一般用于近返回,与call near连用,从栈中弹出2个字节数据存入IP中
retf:远返回,需要跨段,与call far连用,从栈中弹出4个字节存入CS:IP
call
- 16位相对近调用:call near xxxx,这个指令的操作数不是xxxx,相对的概念就是xxxx与当前指令所在地址的相对增量(注意,near的范围可正可负,是有符号整数,如果显式使用会强制改变xxxx的类型)
- 16位间接绝对近调用:call reg_16/mm
- 16位直接绝对远调用:call far 段基址(立即数):段内偏移地址(立即数)
- 16位间接绝对远调用:call far [内存寻址],取该内存的4个字节,低2字节为段内偏移,高2字节为段基址
jmp无条件跳转指令有5种方式,与call差不多分析角度。
1.6:条件转移指令
2:显卡
2.1:外设通信原理
I/O接口的由来:
由于外部设备并没有一个统一的制定标准,所以出现传输速度、驱动信号,串并行、格式的不同,为了让CPU更好的管理外设,额外加一“层”------接口。
I/O接口的定义:
连接 CPU 与外部设备的逻辑控制部件,既为逻辑,就说明可分为硬件和软件两部分。
- 硬件上:做一些实质具体的工作,协调两者间的各种不协调(如实现数据格式的转化,缓冲区的设置降低等待时间)
- 软件上:制作接口电路工作的驱动程序以及完成内部数据传输所需要的程序。
I/O接口的功能:
- 设置数据缓冲,解决 CPU 与外设的速度不匹配
- 设置信号电平转换电路 :外设不能用TTL电平驱动
- 设置数据格式转换:CPU只处理数字信号(即二进制),外设可能是模拟或数字,需用D/A或A/D转换,并且需要判断数字信号的字长和格式进行统一
- 设置时序控制电路来同步 CPU 和外部设备:通过一次握手实现同步(可能需要微机原理才能真正理解)
- CPU发送控制、定时信号给I/O接口
- 接口用它们管理硬件
- 硬件产生应答信号返回接口
- 接口传回CPU
- 提供地址译码:一个接口必须有多个端口(寄存器),同一时刻只能有一个端口与CPU通信,该操作能让CPU选择端口
CPU如何访问I/O接口?如何连接多个进行通信?:
- 总线:一排电线,所有接口都连接其上,但前提是要有电子开关(相当于红绿灯,只有需要通行的路线才会开绿灯),用于断开或者连接总线
- 南桥芯片(ICH):CPU通过内部总线(专用)连进南桥内部,南桥内部有将很多接口集成进电路(PCI接口是专门用于扩展的接口)
下图主板上那些并排的插槽其实都“骑”在一条电线上而已
2.2:显卡
显卡是显示适配器,也是IO接口,用于显示屏与CPU的交互。
显存是显卡的内部一块内存,显卡负责将显存里的数据输入到显示屏中。
字符编码的由来:由于显示器与显存数据的一一对应的,在显示器看来,所有数据都是像素信息,所以要想打印出一些字符,就不得不算出字符对应的像素位置,因为太麻烦了,所以约定俗称的一种编码方式出现了,如显存里存入0x41,显示器就可以输出ASCII对应的字符“A”。字符有了还需要有字符的属性值,所以一个字符需要对应2个字节。
3:磁盘
3.1:磁盘存储逻辑及部件的运动
磁头:每个磁面各有一个磁头来读取数据,从上至下以0开始计数,磁头本身固定,由磁头臂带动着绕着主轴来回摆动
磁道:将整个盘面划分为多个同心环,每个环称为一个磁道
扇区:同心环上的弧状区域是扇形的一部分,称为扇区,是硬盘存储数据的最基本单位,每个扇区512字节,且扇区存在“头部”,用来比对编号。
柱面的作用:为了减少机械式硬盘的寻道时间(减少磁头的移动),当有大于一个磁道空间的连续数据需要存储,其他数据写入第 1 面相同编号的磁道上,若还不够,写到第2面相同编号的磁道上。
所以确定唯一扇区需要“磁头号,磁道号,扇区号。
3.2:主板如何支持硬盘
由于硬盘是外部设备,肯定需要I/O接口,答案是硬盘控制器。
硬盘接口有串行接口(Serial ATA)和并行接口(Parallel ATA),以PATA来说, PATA 接口的线缆也称为 IDE 线,一个 IDE 线上可以挂两块硬盘,主盘和从盘,一块主板支持4个硬盘,所以主板上提供两个 IDE 插槽。 这两个接口也是以 0 为起始编号的,一个称为 IDE0(Primary通道),另一个称为 IDE1(Secondary通道),每个通道都有主从盘。
结束
如有错误,虚心接受指正😄