Intel 8086的内外部结构和内存时序控制
Intel 8086/8088 CPU
目录
图片来自《微型计算机原理与接口技术 (第4版) (吴宁, 乔亚男)》和上课时的PPT
8086和8088的差别不大,有区别的地方会尽量在文中指出
内部结构
在8086之前的CPU的指令周期(取指、译码、执行)都是顺序执行的,而8086设计了一种新的内部结构可以让取指
跟译码和执行
并行处理,这种结构把CPU分为两个独立运行的部件:执行单元EU(Execution Unit)和总线接口单元BIU(Bus Interface Unit)
-
指令队列:EU负责译码和执行,BIU负责取指(如果需要还可以取操作数和写结果),为了实现上面提到的并行操作8086CPU内部设有一个指令队列(6Byte),当队列有空闲时BIU便会自动从内存中取指令到指令队列,当EU译码到跳转指令时,BIU会清空指令队列,从跳转指令处重新开始取指
EU需要数据和运算结束时也都由BIU进行数据传输,且EU不可打断BIU访问总线的过程
-
地址加法器:可以看到BIU中还有一个地址加法器用来运算,它的作用是让16位的内部总线能够寻址20位(1MByte)的外部地址总线,8086采用了将内存分段的管理方式,每个段最大为64KByte(16位偏移地址决定),计算时将16位的段基址左移4位加上段内偏移即可得到20位的内存地址
寄存器
8086共有14个16位寄存器,其中8个通用寄存器、4个段寄存器、2个控制寄存器
-
通用数据寄存器AX、BX、CX、DX:分为高8位和低8位,其名称并不是按字母表起的
A表示Accumulator(累加器),常用于存放算术逻辑运算的操作数,I/O指令也通过AX与外设传送信息
B表示Base(基址寄存器),常用于存放访问内存的基地址
C表示Count(计数寄存器),在循环或串操作中用作计数器
D表示Data(数据寄存器),在寄存器间接寻址的I/O指令中存放I/O地址
在双字节运算时,DX存放高16位,AX存放低16位
-
地址指针寄存器SP、BP:SP存放栈顶偏移地址、BP一般配合SS段寄存器(Stack)使用,存放偏移地址,有时也存放访存的基地址
-
变址寄存器SI、DI:SI(Source Index)源变址寄存器,DI(Destination Index)目的变址寄存器,常在变址寻址中作索引指针
-
段寄存器CS、SS、DS、ES:存放段基址(高16位),分别是代码段、堆栈段、数据段、附加数据段
-
控制寄存器IP、FLAGS:IP指令指针寄存器,用作CS的偏移地址,地址变换后指向下一个要取的指令字节;FLAGS是标志寄存器或程序状态字(PSW),只用了其中的9位
CF进位标志位:加减法运算时,若有进位或借位为1
PF奇偶标志位:运算结果低8位1个数为偶数时为1,相当于对低八位进行奇校验
AF辅助进位标志位:检测加减法操作中低三位向低四位进位借位,可以用在BCD加减法等(BCD码一般使用8421BCD,例如5就是0101,35是0011 0101)
ZF零标志位:运算结果为0时置1
SF符号标志位:运算结果最高位为1时置1
OF溢出标志位:算术运算溢出置1
TF陷阱标志位:TF为1时CPU处于单步执行状态
IF中断允许标志位:0时会屏蔽可屏蔽中断,软件屏蔽的途径就是IF
DF方向标志位:执行串操作时的方向控制,1时地址递减、0时相反
内存组织
8086内部总线是16位的,只能提供64KByte的内存管理能力,为了提高内存,其外部地址总线设置为20位(1MByte),并且采用分段管理的方式来适应这种内外不同的总线位数,正如上文地址加法器所描述
逻辑地址:由于段基址和段内偏移地址需进一步计算才可以得到实际物理地址,因此将他们称为逻辑地址,通常记作
8086有4个段寄存器,段与段之间是可以重叠的,因此一个物理地址可以用多个逻辑地址表示
使用分段后引入的偏移地址还能够实现程序在装入内存时的可重定位,用于操作系统做内存管理
8086对不同操作分配了不同的段寄存器,其中有些段寄存器可以被其他寄存器替代(在程序设计时表明),而有些不能如下表:
访存操作 | 默认段寄存器 | 替代寄存器 | 偏移地址 |
---|---|---|---|
取指令 | CS | 无 | IP |
堆栈操作 | SS | 无 | SP |
串操作的源串 | DS | ES、SS | SI |
串操作的目标串 | ES | 无 | DI |
BP 用作基址寻址 | SS | ES、DS | 按照寻址方式计算 |
一般数据存取 | DS | ES、SS | 按照寻址方式计算 |
工作时序
时序可以分为不同的粒度,一个指令周期可能需要多个总线周期,一个总线周期又需要多个时钟周期
- 时钟周期:处理器在运行时是按照统一的时钟一步一步执行操作的,这个基本的时钟脉冲的持续时间就是时钟周期
- 总线周期:CPU与内存或者其他外设通信都通过总线进行,这种通过总线进行读或写的过程称为一个总线周期
此处是8088最小模式下的时序图简化
在8088的总线周期中,至少由4个时钟周期(
:在此期间总线上是CPU输出的访存地址,并且配合ALE的高电平,将总线上的地址信息锁存到地址锁存器中 :该周期主要用于时分复用引脚的状态转换 :该周期开始会采样READY引脚,并且根据引脚内容在该周期后插入 周期,详情见引脚部分对 的说明 :首先,CPU在 信号的后沿进行,这样能保证总线数据的稳定。若是写总线,则CPU一直维持三个时钟周期宽度( )的数据总线信息;在读总线时,如上图所示是在大约 开始时
引脚
此处的是8088的CPU引脚图,其中括号内的功能是最大模式下的功能,画有/
的表示引脚功能时分复用,8086的引脚与8088引脚仅有以下几处不同:
- 在28号引脚最小模式下功能对应的电平相反
- 在34号引脚8086是
- 在2-8号引脚8086有数据总线接口,相应的也是双向信号线
最小模式
-
:三态输出,在某一时序状态下引脚用作地址信号的高4位,发出地址;而在其他时序下引脚用作状态信号输出。 -
:恒为0 -
:指示中断允许标志位的状态 -
:指示正在使用的段寄存器
段寄存器 | ||
---|---|---|
0 | 0 | ES |
0 | 1 | SS |
1 | 0 | CS或未使用 |
1 | 1 | DS |
-
:三态输出,中8位地址信号用于CPU寻址 -
:三态双向信号线,当 引脚为高电平表示传输地址信号,当 引脚为低电平表示传输数据信号 -
:三态输出,用来区别寻址对象是存储器还是I/O端口,高电平表示I/O,低电平表示存储器 -
:三态输出,低电平表示CPU正在进行写操作,写的对象由 控制 -
:三态输出,用于控制总线收发器8286/8287的数据传送方向,高电平表示CPU发送数据,低电平表示CPU接收数据 -
:三态输出,低电平表示数据总线上的数据有效 -
:三态输出,高电平表示CPU地址总线上的地址有效 -
:三态输出,低电平表示CPU正在进行读操作,读的对象由 控制 -
:输入,外部同步控制信号,由被访问的设备发出,高电平表示设备已准备好,CPU可以传送数据,低电平表示未准备好,相应的CPU会在 (在此周期采样READY)后插入若干等待周期 ,直到READY为高电平 -
:输入,在每个指令周期的最后一个周期采样INTR,若高电平CPU会进入中断确认操作,此信号可用软件屏蔽 -
:输入,当CPU执行WAIT指令时,每隔5个时钟周期对此引脚进行采样,若为低电平则结束等待状态,CPU继续执行指令 -
:输入,上升沿触发,当CPU执行完指令后立即进入中断处理,不可用软件屏蔽 -
:输入,高电平有效且至少持续4个时钟周期,在下降沿CPU将重新启动,复位后除了CS寄存器其他寄存器包括指令队列全部清零 -
:输出,用于CPU对中断请求信号INTR的响应,在响应过程中CPU连续输出两个负脉冲用作外部中断源的中断向量码的读选通信号 -
:输入,当某一总线主控设备要占用系统总线时,通过此引脚高电平向CPU提出请求 -
:输出,高电平有效,是CPU对HOLD的响应,高电平CPU交出总线控制权,并且将所有三态输出的地址、数据和相应的控制信号变为高阻状态(CPU输出不会影响总线),当HOLD信号变低时就会使HLDA变低,恢复总线控制权 -
:输出,与 和 决定最小模式下当前总线周期的状态;需要注意的是8086拥有16位地址总线,在8086中此引脚定义为 , 低电平允许数据在总线的高半部分进行传输,在8086进行存储时可能会存在数据未对齐的现象,也就是16位的数据的低8位的内存地址是奇地址,这个时候由于8086的偶地址单元在数据总线低8位上传输,奇地址单元的数据在数据总线高8位上传输,导致在一个总线周期只能先通过数据总线的高8位取得未对其数据的低8位内容,,然后再在下一个总线周期通过数据总线的低8位取得未对其数据的高8位内容, 可以在第二次取数据时防止地址总线高八位被覆盖,达到组合两次总线周期取数结果的效果; 是状态位有效位为低电平, 有效,HOLD进入高阻态,中断确认周期的 为低电平
操作 | |||
---|---|---|---|
0 | 0 | 0 | 取指令 |
0 | 0 | 1 | 读内存 |
0 | 1 | 0 | 写内存 |
0 | 1 | 1 | 无作用 |
1 | 0 | 0 | 发出中断响应信号 |
1 | 0 | 1 | 读I/O |
1 | 1 | 0 | 写I/O |
1 | 1 | 1 | 暂停 |
:输入,时钟信号 :5V电源输入 :地线
最大模式
:输入,最大模式下此引脚为低电平 :三态输出,连接总线控制器8288的输入,8288负责对其译码并产生各种操作
操作 | |||
---|---|---|---|
0 | 0 | 0 | 取指令 |
0 | 0 | 1 | 读内存 |
0 | 1 | 0 | 写内存 |
0 | 1 | 1 | 无作用 |
1 | 0 | 0 | 发出中断响应信号 |
1 | 0 | 1 | 读I/O |
1 | 1 | 0 | 写I/O |
1 | 1 | 1 | 暂停 |
:双向信号线,都是总线请求和相应,但 优先级高,其他总线控制设备请求时,向 引脚发生一个时钟周期宽的负脉冲(最小模式下的HOLD),CPU检测到后,在下一个指令周期的 期间,在 发出一个时钟周期宽的负脉冲响应信号(最小模式的HLDA),然后下一个时钟周期开始CPU释放总线,设备使用完后再次产生一个 信号,CPU检测到后从下一个时钟周期开始重新控制总线 :输出,低电平时CPU锁定总线,不允许其他设备申请控制总线,由前缀指令LOCK产生,LOCK后的一条指令执行完毕后, 失效 :输出,表示指令队列状态
CPU状态 | ||
---|---|---|
0 | 0 | 无操作 |
0 | 1 | 正在取队列中操作码的第一个字节 |
1 | 0 | 队列空 |
1 | 1 | 正在取队列中非第一个操作码字节 |
:输出,最大模式下始终为高电平
CPU子系统
8086最小模式的一种CPU子系统的设计
-
373指的是74LS373,是一个8位的锁存器,在8086中两片373用来所存低16位地址,一片存放高4位地址和
信号,可以看到所有的373都连接了 引脚来获取地址是否有效的状态信息(控制373的数据是否更新) -
245指的是74LS245,是8位三态双向总线收发器,可以看到两片245都连接了
和 ,分别用于控制数据导通方向和是否导通,上面时序部分我们提到数据在 的开始阶段才读写,这里我个人认为其实是由于 引脚的低电平一直持续到 开始 -
244作用尚且未知,待更新
8086最大模式下的一种CPU子系统
- 可以看到加了一个8288用做对状态信号的译码,并产生各种总线控制信号
本文作者:幻星晞
本文链接:https://www.cnblogs.com/huanxx/p/18750443
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」