- 打算整理汇编语言与接口微机这方面的学习记录。本部分讲解8086CPU的结构和基本功能以及特性。
- 参考资料
- 西电《微机原理与系统设计》周佳社
- 西交《微机原理与接口技术》
- 课本《汇编语言与接口技术》王让定
- 小甲鱼《汇编语言》
1. 微处理器的外部结构
1.1 引脚
外部结构就是封装出来的输入输出引脚。8086/8088有40个引脚。
- 8086片内片外的数据总线都是16位
- 8088片内16位,而片外8位
如此前绪论所说,部分引脚专用,部分引脚复用,复用部分需要掌握其时序。
CPU的这些引脚功能:
- 与存储器之间交换信息
- 与I/O设备(接口)之间交换信息
- 输入输出必要的信息
1.2 控制引脚
举个例子讲解一下这些引脚:
-
当CPU向外部(存储器/IO接口)写数据时,上图的WR引脚应为有效(低电平)
RD是读信号。
-
而区分操作存储器和I/O接口的是M/IO引脚
-
在此基础上可以设计逻辑电路来控制更具体的事情,比如WR和M/IO连接一个或门,就能产生IOW信号等。
1.3 地址引脚
A. 寻址空间
8086CPU有20条地址线A19A<sub>16</sub>、A<sub>15</sub>A0,可以寻址\(2^{20}\)字节的空间,也就是1M空间,地址空间大小为1MB。
B. IO端口的概念
- 操作系统设计过程中,外设部分经常提及端口,这里正经回忆一下。
- 外设的状态存储在接口电路中的端口寄存器,如果CPU没有与接口通信,则端口寄存器保持高阻态,不向外/内输出、输入。
- 当地址总线上的地址是某接口端口寄存器的地址(选中)时,其中信息通过数据总线流入CPU。
总线竞争:多个设备端口同时激活。
端口如下图右下角部分所示:
- 数据输入端口
- 命令端口
- 状态输入端口
具体而言,外设芯片是有手册的,当我们操作显卡,就要查VGA相关的手册,鼠标和键盘就有另一个芯片来管理。
手册上会详细说明端口的作用,在程序中用指令向端口赋值即可。
C. 统一编址与独立编址
上面提到,一个IO端口至少占用一个IO地址----IO端口地址。根据端口地址和存储器是否一起编址,有:
-
统一编址
- 缺点:浪费了存储器的空间。
- 优点:IO驱动程序编写方便,灵活。
- 例:51系列。
-
独立编制
- 优点:节约存储器的空间。
- 缺点:要多记忆操作IO的指令,IO编程不灵活。
- 例:8086。
- x86的IO访存指令为 in/out
举个例子
某个I/O端口的地址为2000H,则访问如果要输出数据到该端口,汇编语言应该这样写:
mov AL,01H ;这里是要输出的数据量,仅是一个参考 ;该课程中这里要点一个灯 mov DX,2000H mov DX,AL ;注意这里跟存储器的并不同,没有中括号
2. 微处理器的内部结构
2.1 作用
2.2 结构
不论CPU型号如何,其内部基本都有以下结构:
-
ALU:必须,算术逻辑运算
-
地址寄存器可以充当数据寄存器
数据寄存器不能充当地址寄存器
-
控制器:负责取指令,放在指令寄存器中,译码
-
I/O控制逻辑:与外部I/O打交道,使得CPU可以响应I/O设备发出的中断请求。
2.3 控制器讲解
这部分要与其实跟计组没多大差别了,要结合CPU"取指执行"的思想来理解。
学到这里突然想复习 流水线 Verilog 什么的了。
因为上面的图还是很笼统,怎么判断、怎么控制时序都还没有涉及。先忍住,把接口部分学完。
上图并不完整,如果从存储器中取出的是数据data而不是指令 instructions ,则直接放入数据寄存器或者指定寄存器(也不属于控制器的范畴了)
2.4 堆栈
来自计操的补充:
- 说 堆 特指 堆
- 说 堆栈 指的是 栈
-
堆栈在存储器空间中,大小和位置都是编程自定义的。
-
8086中堆栈必须按字操作
-
堆栈操作的代表性指令是
push ax pop ax ;如果是8086的按字操作规定,目的寄存器就不能是AL
-
堆栈基址寄存器:sp,初始置向栈底+1(也就是栈底再向下的一个存储单元),这个位置是程序设定的。
-
假如执行以下操作:
push ax;第1步 push bx;第2步
第1步中,sp先-2空出一个字,然后AX分高低八位分别存入这个空字的高低存储单元。
第2步重复第1步操作。
如果要pop堆栈中的值,则是上述逆过程,先取出栈顶的值,再sp+2。
-
堆栈溢出:
- 当一直push,向堆栈区域增加数据,超过堆栈分配空间(超过最高栈顶),则溢出
- 当一直pop,超过栈底,则溢出。
- 堆栈溢出会造成系统crush。
3. 8086/8088CPU 内部结构
2.3节讲解的是处理器的工作思路,或是说 “取指执行”的计算机思想。下面介绍8086CPU的内部结构(仍然符合2.3节的大致思路)。
3.1 BIU
-
有一个问题,地址总线20位,意味着可以寻址1MB地址空间;而CPU内部寄存器只有16位。
如何用16位寄存器存放20位的地址信息呢?
-
8086的设计是:讲存储器分为逻辑段,一个寄存器负责寻址段,一个寄存器负责寻址段内空间,也就是一个段内最多64KB(\(2^{16}\)byte)空间。
-
各种段基址寄存器以及指令寄存器就在上图BIU右上角
-
这里的转化的具体过程就是在上图的地址产生与总线控制单元进行的。
-
转化公式为:
CS:IP(CS左移4位+IP),也就是
(CS << 4) + IP
-
BIU右下角的指令队列充当的是2.3节的IR指令寄存器的角色,8086中有6个字节,8088中4个字节。
这是两个CPU内部结构唯一的区别。
总结,BIU负责外部存储器取出指令、取出数据,并将取出的指令放入指令队列,对应 “取指”。数据通过ALU总线直接送入EU。
3.2 EU
总结放在前面:负责从指令队列中获取指令,对该指令译码并执行,对应“执行”。
这里可以看出,指令队列的存在,可以使得两个部分的性能都得到提升。
而外部总线在上图过程中始终处于忙状态,总线的使用率也上升。
4. 8086的寄存器组织
8086内部共有14个16位寄存器:
-
通用寄存器 (EU左上角)
- 数据寄存器 4个
- AX,BX,CX,DX
- 各个寄存器又有特殊功能,但是给我的印象不深:
- AX—累加器(特殊功能)| AH AL
- BX—基址寄存器(特)—段内的–DS段的
- CX—计数器
- DX—数据寄存器(IO)
- 它们又都可以分为XH和XL。
- 数据寄存器 4个
-
地址指针寄存器与变址寄存器
-
地址指针寄存器
-
SP:堆栈指针寄存器
-
BP:地址指针寄存器
2023-02-20!!!注意SP和BP的区别:ss栈段寄存器,sp栈顶指针寄存器sp会随着带有堆栈操作的指令(比如PUSH、CALL、INT、RETF)产生变化,而BP不会,所以在带参数的子过程中用BP来获取参数和访问设在堆栈里面的临时变量。
BP与BX在做地址指针时的区别:
mov BX,002H mov BP,002H mov AL,34H mov [BX],AL;1 mov [BP],AL;2
1处AL值默认放到了数据段的BX偏移处,2处AL值默认放到了堆栈段的BP偏移处。
如果要使它们不默认,可以将上面代码表示地址的中括号内加上它们的目的段基址寄存器如:
mov SS:[BX],AL ;此时BX表示
-
-