复习日志:微型计算机原理及接口技术
基本概念
- 例题:接口的基本功能就是(C)与(D)。
- A. 输出锁存
- B. 输入锁存
- C. 输出缓冲
- D. 输入缓冲
- 解析:
- 输入缓冲:输入缓冲用于接收外部设备发送的数据,并将其暂存,以便 CPU 能够稳定读取。它可以防止外部信号的抖动或不稳定影响 CPU 的工作。
- 输出缓冲:输出缓冲用于暂存 CPU 发送的数据,并将其稳定地传输到外部设备。它可以确保数据在传输过程中不会丢失或失真。
- 锁存功能:锁存功能通常用于在特定时刻保存数据,但它不是接口的基本功能。锁存功能通常由专门的锁存器实现,而不是接口的核心功能。
- 一个外设最多可含有控制端口、数据端口、状态端口三种类型的端口。
汇编语言
端口 I/O
- 向外设端口输出一个数据的指令是:
OUT DX, AL
。 - 向外设端口输入一个数据的指令是:
IN AL, DX
。 - 8086 CPU 在执行
IN AL, DX
指令时,DX 寄存器的内容输出到地址总线上 。- 在指令
IN AL, DX
中,DX 寄存器的内容是端口地址,而 8086 CPU 在执行此指令时会通过地址总线 将端口地址传递给输入/输出 (I/O) 设备,然后通过数据总线获取从该端口读到的数据。IN AL, DX
指令的作用是从 DX 指定的端口读取数据,并将其存入 AL 寄存器中。- DX 寄存器包含的是端口地址。CPU 通过地址总线将这个端口地址发送到 I/O 设备。
- 然后,设备会将数据通过数据总线传送到 AL 寄存器。
- 换句话说,DX 寄存器的内容(端口地址)会通过地址总线被传送到设备,而读取的数据会通过数据总线被送到 AL 寄存器。所以,虽然最终数据是通过数据总线传送到寄存器,但 DX 寄存器本身决定了端口地址,而端口地址是通过地址总线传递的。
- 在指令
OUT
指令的语法:OUT port, AL
:将AL
中的 8 位数据输出到指定的 8 位端口。OUT port, AX
:将AX
中的 16 位数据输出到指定的 16 位端口。- 端口地址的范围:
- 如果端口地址是 8 位(范围:
00H
到FFH
),可以直接在指令中指定。
OUT 20H, AL
- 如果端口地址是 16 位(范围:
0100H
到FFFFH
),必须先将端口地址加载到DX
寄存器,然后使用DX
作为端口地址。
MOV DX, 2000H OUT DX, AL
数据传送指令
- 交换寄存器值
- 使用
XCHG
指令:XCHG AX, BX
。 - 使用
MOV
指令:
MOV CX, AX; 将 AX 的值保存到临时寄存器 CX MOV AX, BX; 将 BX 的值复制到 AX MOV BX, CX; 将临时寄存器 CX 的值复制到 BX
- 使用堆栈进行交换:
PUSH AX MOV AX, BX POP BX
- 使用
转移指令
在 8086/8088 汇编中,转移指令分为段内转移和段间转移。
段内转移指令
- 特点:
- 段内转移指令只改变 IP(Instruction Pointer)的值,而不改变 CS(Code Segment)的值。
- 因为段内转移是在当前代码段内跳转,所以不需要改变段地址。
- 示例:
JMP
指令(段内跳转):JMP LABEL
。- 这条指令只会修改
IP
,而不会修改CS
。
段间转移指令
- 特点
- 段间转移指令会同时改变 IP 和 CS 的值。
- 因为段间转移需要跳转到另一个代码段,所以需要修改段地址。
- 示例:
JMP FAR
指令(段间跳转):JMP FAR PTR LABEL
。- 这条指令会同时修改
IP
和CS
。
指令前缀
在 8086/8088 处理器中,REP
是一个指令前缀,用于重复执行接下来的字符串操作指令(如 MOVSB
, MOVSW
, CMPSB
, CMPSW
等)。它会根据 CX
(计数寄存器)的值决定重复的次数:
- 如果
CX ≠ 0
,则指令会重复执行。 - 每执行一次操作后,
CX
的值会自动减少,直到CX
为 0 时停止。 因此,REP
指令前缀的功能是根据CX
寄存器的值来决定是否继续执行重复操作。
汇编语言变量定义
变量名DB表达式 ;定义字节变量,即8位(1字节)变量
变量名DW表达式 ;定义字变量,即16位(2字节)变量
变量名DD表达式 ;定义双字变量,即32位(4字节)变量
变量名DQ表达式 ;定义长字变量,即64位(8字节)变量
变量名DT表达式 ;定义一个10字节的变量
- 例题:执行下列指令后寄存器 CL 的值就是(D)。
- A. 0FH
- B. 0EH
- C .12H
- D. 10H
STR1 DW 'NO'; 定义一个双字节变量 'NO',占 2 字节。
STR2 DB 14 DUP(?); 定义一个 14 字节的未初始化数据块。
CONT EQU $-STR1; 定义了一个符号常量 `CONT`。`STR1` 到当前位置的字节数。
MOV CX, CONT; CX = 16 = 0010H。CL 值只考虑低 4 位,即 10H。
MOV AX, STR1; 将 `STR1` 的地址加载到 `AX` 寄存器中。
HLT; 此指令停止程序的执行。
- 例题:下面指令执行后,变量 DAB 中的内容就是(C)。
- A. ODAH
- B. 0FAH
- C. 0F5H
- D. 0D0H
DAW DW 2A05H; 定义一个字(2字节)变量 `DAW`,值为 `2A05H`。
DAB DB OFAH; 定义一个字节变量 `DAB`,值为 `0FAH`。
MOV AL, BYTE PRT DAW; `BYTE PTR DAW` 表示取 `DAW` 的低字节。`DAW` 的值为 `2A05H`,低字节是 `05H`。因此,`AL = 05H`。
SUB DAB, AL; 计算:`0FAH - 05H = 0F5H`。结果存入 `DAB`,因此 `DAB = 0F5H`。
8086 CPU
- 8086 CPU 有 16 条数据总线、20 条地址总线和 16 条控制总线。
- 当有两个 8286 时,可为 8086CPU 提供数据总线。
- 当使用两个 8286 数据收发器时,可以为 8086 CPU 提供完整的 16 位双向数据总线接口,这是因为每个 8286 提供 8 位双向数据总线。
- 8086 CPU 通过总线对外部(存储器或 I/O 接口)进行一次访问所需的时间称为一个总线周期。一个总线周期至少包括 4 个时钟周期即 $T_1$、$T_2$、$T_3$ 和 $T_4$。
- 例题:8086/8088 的一个典型总线周期需要 4 个 T 状态。
内部结构
从 CPU 的内部结构可以看出,CPU 由四部分构成:算数逻辑运算单元 (ALU)、工作 寄存器、控制器和 I/O 控制逻辑。
- 算术逻辑单元:它是运算器的核心,完成所有的运算操作。它是一个组合电路,无 记忆功能。它有两个输入端和一个输出端,在控制信号的控制下可以完成不同的操作。
- 工作寄存器:可以暂存寻址信息和计算过程中的中间结果。数据寄存器用于暂存操 作数和中间结果,地址寄存器用于暂存操作数的寻址信息。
- 控制器:它是 CPU 的“指挥中心”,完成指令的读入、寄存和译码,并产生控制信号序列,使 ALU 完成指定的操作。控制器由下列部件组成。
- 程序计数器 (program counter,PC):用于保存下一条要执行的指令的地址,也称指令指针 (instruction pointer)。
- 指令寄存器 (instruction register,IR):保存从存储器中读入的当前要执行的指令。
- 指令译码器 (instruction decoder,ID):对指令进行译码。
- 控制逻辑部件:根据对指令译码的分析,产生控制信号,以完成指令规定的操作。
- 微处理器状态字 (processor state word,PSW):寄存处理器当前的状态,如指令结 果是否为 0,结果是正是负,有没有进位、借位,是否溢出等。
- 堆栈指针 (stack pointer,SP):指示堆栈的地址。
- I/O 控制逻辑:处理 I/O 操作。
- 例题:8086 CPU 的 40 根引脚中,有 21 个就是分时复用的。
- 这 21 根分时复用引脚是:
- AD0 - AD15:这 16 根引脚在不同的时钟周期上既作为地址总线,也作为数据总线(即复用了地址和数据功能)。
- A16 - A19:这 4 根引脚在低时钟周期时用作地址引脚,在高时钟周期时用作控制信号。
- ALE:地址锁存信号,控制地址总线的数据锁存。
- 这 21 根分时复用引脚是:
- 例题:8086 系统的存储器中各段的大小固定为 64KB,同时各段之间可以重叠。
- 例题:总线控制器 8288 专门用于 8086 最大模式下产生控制信号。
寄存器组织
通用寄存器
通用寄存器可以分成两类:数据寄存器 (AX、BX、CX、DX) 和地址指针/变址寄存器 (SI、DI、SP、BP)。
- 例题:若当前 DS 的内容为 2000H,则偏移量为 1000H 单元的地址可表示为 21000H。
- 解析:在 x86 架构中,内存地址是由段地址和偏移量组合起来的。地址的计算方式如下:$\text{物理地址} = (\text{段地址} \times 16) + \text{偏移量}$。由此可以计算得到:$2000H \times 16 + 1000H = 21000H$。
- 例题:8086 CPU 复位后,CPU 执行的第一条指令的起始地址应就是
RAM, FFFF0H
。- 在 8086 CPU 复位后,CPU 的程序计数器(CS:IP)被初始化为一个特定的值,以确定从哪里开始执行第一条指令。这与 CPU 的设计有关。
- CS (代码段寄存器) 被初始化为
FFFFH
。 - IP (指令指针寄存器) 被初始化为
0000H
。
- CS (代码段寄存器) 被初始化为
- 根据 8086 的段: 偏移地址模式,物理地址的计算公式为:$\text{物理地址} = (\text{CS} \times 16) + \text{IP}$。将初始值代入公式:$\text{物理地址} = (FFFFH \times 16) + 0000H = FFFF0H$。
- 在 8086 CPU 复位后,CPU 的程序计数器(CS:IP)被初始化为一个特定的值,以确定从哪里开始执行第一条指令。这与 CPU 的设计有关。
数据寄存器
8086 CPU 有 4 个 16 位数据寄存器。
- 累加器 (accumulator,AX):这是最常用的寄存器,许多操作都可以在 AX 中完成,而且有一些操作只能在 AX 中完成,如乘法和除法操作。
- 基址寄存器 (base register,BX):虽然属于数据寄存器,但它经常用作地址寄存器。
- 计数寄存器 (count register,CX):经常用作循环的计数寄存器,如在循环语句中,默认 CX 的内容为循环次数。
- 数据寄存器 (data register,DX):用于寄存数据,但在 I/O 指令中,DX 用于表示端口地址。 另外,这 4 个 16 位的数据寄存器又可以分成 8 个 8 位的字节寄存器:
AX → AH, AL
BX → BH, BL
CX → CH, CL
DX → DH, DL
其中,“H” 表示高 8 位 (高字节),“L” 表示低 8 位 (低字节),在程序设计中可以独立使用这 8 个字节寄存器。
地址寄存器
8086 CPU 有 4 个 16 位的地址寄存器。
- 变址寄存器 (source index,SI):在字符串操作指令中,SI 提供源操作数的段内偏移地址,当然也可以在其他指令中,用作地址寄存器。
- 变址寄存器 (destination index,DI):在字符串操作指令中,DI 提供目的操作数的段内偏移地址,当然也可以在其他指令中,用作地址寄存器。
- 堆栈指针 (stack pointer,SP):用于保存堆栈段的段内偏移地址。段地址由段寄存器 SS 提供。堆栈是一块特殊的内存区域,它以“先进后出”的方式保存各寄存器、返回地址等信息。
- 基址指针 (base pointer,BP):BP 可以指定段内偏移地址,但将 BP 用作地址寄存器时,一般情况下,其默认的段地址为 SS。 在将这 4 个寄存器 (SI、DI、SP、BP) 用作地址寄存器时,它们只提供了 16 位的偏移地址。要形成 20 位的物理地址,还需要由段寄存器提供段地址,它们之间的关系为:$\text{物理地址} = \text{段地址} \times10 H + \text{偏移地址}$。
- 合法的内存寻址方式:
[BX + SI]
[BX + DI]
[BP + SI]
[BP + DI]
[SI + 偏移量]
[DI + 偏移量]
[BX + 偏移量]
[BP + 偏移量]
段寄存器
8086 CPU 的段寄存器有 4 个。
- 代码段 (code segment,CS) 寄存器:用于存放当前执行程序的段地址,IP 为指令指针。
- 数据段 (data segment,DS) 寄存器:用于存放当前数据段的段地址。
- 附加段 (extra segment,ES) 寄存器:用于存放当前附加数据段的段地址。
- 堆栈段 (stack segment,SS) 寄存器:用于存放当前堆栈段的段地址。 由段地址和偏移地址可以构成物理地址,这一点与存储器的分段结构有关。
- 在 8086/8088 指令集中,
PUSH
指令可以用于将段寄存器(如CS
、SS
、DS
、ES
)的值压入堆栈。 - 例题:在 8086/8088 系统中,堆栈操作所访问的段是由 SS(Stack Segment)寄存器指定的,而不是由 ES(Extra Segment)寄存器指定的。
控制寄存器
8086 CPU 有两个控制寄存器。
- 指令指针 (instruction pointer,IP):也称程序计数器 (program counter,PC),用于保存下一条即将要执行指令的段内偏移地址。改变 IP 的值就意味着改变程序的流程,不能通过普通的传送类指令修改 IP 的值,但某些指令可以改变 IP 的内容,如转移指令、子程序调用和返回指令等。
- 微处理器状态字 (processor state word,PSW):它是一个 16 位的寄存器,一共设定了 9 个标志位,其中 6 个标志位用于反映 ALU 前一次操作的结果状态,另 3 个标志位用于控制 CPU 操作。
反映 ALU 前一次操作结果状态的标志位如下。
- 进位标志 (carry flag,CF):在加减运算时,最高位 (D7 或 D15) 有无进 (借) 位的标志。
- 奇偶标志 (parity flag,PF):操作结果的低 8 位中含有”1“的个数。
- 辅助进位标志 (auxiliary carry flag,AF):在加减运算时,D3 位有无进 (借) 位的标志。
- 零标志 (zero flag,ZF):运算结果是否为 0。
- 符号标志 (sign flag,SF):操作结果的符号,它等同于操作的最高位 D7(或 D15)。
- 溢出标志 (overflow flag,OF):有符号数运算时是否溢出的标志。
- 例题:下列指令执行后总就是使 CF = 0,OF = 0 的就是(A)。
- A. AND
- B. NEG
- C. NOT
- 解析:
- A.
AND
指令:AND
是逻辑与操作,按位与运算。- 对标志位的影响:
- CF 会被清零。
- OF 会被清零。
- 符合条件:
CF=0
,OF=0
。
- B.
NEG
指令:NEG
是取负操作,计算二进制补码。- 对标志位的影响:
- 如果操作数为
0
,CF 会被清零;否则,CF 会被置1
。 - 如果结果超出范围,OF 会被置
1
。
- 如果操作数为
- 不符合条件:
CF
和OF
可能为1
。
- C.
NOT
指令:NOT
是按位取反操作。- 对标志位的影响:
- CF 和 OF 不受影响(保持不变)。
- 不符合条件:
CF
和OF
可能不为0
。
- A.
通用传送指令的数据传送路径
- 例题:(A)寻址方式的跨段前缀不可省略。
- A. DS:[BP]
- B. DS:[SI]
- C. DS:[DI]
- D. SS:[BP]
- 解析:在 x86 架构中,跨段寻址是指访问的数据不在当前段内,而是在其他段内。为了确保正确的寻址和数据访问,处理器使用段寄存器来指定访问的段。某些寻址方式需要明确的跨段前缀,以确保数据的正确访问。
- A. DS:[BP]。DS(数据段寄存器)通常用于访问数据。[BP]是基于 BP 寄存器的偏移寻址,通常用于栈段中的数据访问。这个寻址方式是跨段寻址,因为 BP 通常指向栈段(SS),而 DS 指向数据段。需要跨段前缀,即必须显式地指定段寄存器(如 DS)来避免冲突。
- B. DS:[SI]。DS(数据段寄存器)和 SI(源索引寄存器)用于字符串操作或数组访问。在 DS 中进行数据寻址时,SI 是用来存放偏移量的。这通常是同段寻址,不需要跨段前缀。
- C. DS:[DI]。DI(目标索引寄存器)用于字符串操作或数组访问,类似于 SI。DS:[DI]是同段寻址,不需要跨段前缀。
- D. SS:[BP]。SS(栈段寄存器)和 BP(基指针寄存器)用于栈的访问。由于栈总是通过 SS 寄存器访问,因此 SS:[BP]是栈段寻址,并且不需要跨段前缀。
- 例题:下列存储器操作数的跨段前缀可省略的就是(B)。
- A. DS:[BP]
- B. SS:[BP]
- C. ES:[BX]
- D. ES:[SI]
- 例题:下述指令,正确的指令就是 (D)(设 BUF 就是字节变量,LAB 为标号)。
- A.
MOV BX, AL
- B.
MOV BX, BUF
- C.
MOV BX, LAB
- D.
MOV BX, OFFSET BUF
- 解析:
- 选项 A:
MOV BX, AL
。AL 是一个字节寄存器,而 BX 是一个字寄存器。字节寄存器(如 AL)与字寄存器(如 BX)不能直接进行数据传送,因为它们的大小不一致。 - 选项 B:
MOV BX, BUF
。BUF 是一个字节变量,而 BX 是一个 16 位寄存器。字节变量(如 BUF)通常代表的是一个内存地址或存储空间的内容,但MOV BX, BUF
不能直接将一个字节变量的值存储到一个 16 位寄存器中,除非 BUF 代表的是一个内存地址,这样应该使用MOV BX, OFFSET BUF
。 - 选项 C:
MOV BX, LAB
。LAB 是一个标号。标号通常指向程序中的某个地址位置,直接把标号赋值给 BX 寄存器是错误的,因为标号需要通过计算地址偏移量来处理。 - 选项 D:
MOV BX, OFFSET BUF
。OFFSET BUF
是 BUF 变量的地址。MOV BX, OFFSET BUF
是合法的指令,它将 BUF 的地址(即偏移量)加载到 BX 寄存器中。OFFSET
是用来获取变量或数据的内存地址的关键字。
- 选项 A:
- A.
- 立即数 $\rightarrow$ 通用寄存器或存储单元。
MOV AX, 0210H; (AX) ← 0210H
MOV VAR2, 27H; (VAR2) ← 27H
- 通用寄存器 $\rightarrow$ 存储单元。
MOV [BX], AX; ((BX)) ← (AX)
MOV [DI], AL; ((DI) + 4) ← AL
- 存储单元 $\rightarrow$ 通用寄存器。
MOV AX, [SI]; (AX) ← ((SI))
MOV DX, VAR1 + 5; (DX) ← (VAR1 + 5)
MOV BL, BYTE PTR VAR1 + 5; (BL) ← (VAR1 + 5)
- 通用寄存器 $\leftarrow\rightarrow$ 通用寄存器。
MOV AX, BX; (AX) ← (BX)
MOV DL, AL; (DL) ← (AL)
- 通用寄存器 $\leftarrow\rightarrow$ 段寄存器。
MOV BX, ES; (BX) ← (ES)
MOV DS, AX; (DS) ← (AX)
- 段寄存器 $\leftarrow\rightarrow$ 存储单元。
MOV DS, [SI + 2]; DS ← ((SI) + 2)
MOV [DI], ES; ((DI)) ← ES
注意: MOV 指令不能直达的路径。
- 立即数 $\times\rightarrow$ 段寄存器。
- 存储单元 $\times\rightarrow$ 存储单元。
- 段寄存器 $\times\rightarrow$ 段寄存器。 如果要完成数据在这些路径上的传送,则应该分以下步骤操作。
- 立即数 $\rightarrow$ 段寄存器。一般可以通过立即数 $\rightarrow$ 通用寄存器 $\rightarrow$ 段寄存器来完成,例如:
MOV AX, 3A01H
MOV DS, AX; (DS) ← 3A01H
- 存储单元 $\rightarrow$ 存储单元。一般可以通过存储单元 $\rightarrow$ 通用寄存器 $\rightarrow$ 存储单元来完成,例如:
MOV AX, VAR1
MOV [DI + 10], AX; ((DI) + 10) ← VAR1
- 段寄存器 $\rightarrow$ 段寄存器。一般可以通过段寄存器 $\rightarrow$ 通用寄存器 $\rightarrow$ 段寄存器来完成,例如:
MOV AX, CS
MOV DS, AX; (DS) ← (CS)
- 应该注意,CS 不能作为目的寄存器。
中断响应
- 外部可屏蔽中断(INTR):中断允许标志位 IF = 0 时,微处理器不响应请求;IF = 1 时,微处理器响应请求。
- 外部非可屏蔽中断(NMI):只要 NMI 信号有效,8086 现行指令执行结束都会响应 NMI 中断请求。
- 内部中断:内部中断是执行 INT n 、INTO 等指令,或由于除法出错,或进行单步操作而引起的中断。
8086 CPU VS. 8088 CPU
特性 | 8086 | 8088 |
---|---|---|
数据总线宽度 | 16 位数据总线 | 8 位数据总线 |
内存寻址能力 | 1 MB(20 位地址总线) | 1 MB(20 位地址总线) |
性能 | 更高的数据传输速度和处理能力 | 较低的数据传输速度和处理能力 |
指令集架构 | 完全相同,16 位架构 | 完全相同,16 位架构 |
外部总线宽度 | 16 位 | 8 位 |
时钟周期与速度 | 适用于高性能需求 | 适用于低成本应用 |
应用场景 | 高性能计算和嵌入式应用 | IBM PC 和低成本个人计算机 |
- 8086 的外部数据总线是 16 位的,因此每个总线周期可以传输 2 字节的数据。8088 微处理器是一种 16 位处理器,但其外部数据总线是 8 位的。因此,每个总线周期只能交换 1 字节的数据。
- 例题:由 8088 CPU 组成的 PC 机的数据线就是 8 条双向线。
- 在 8088 微处理器中,取指令和执行指令可以重叠操作,这是通过流水线技术实现的。
- 在 8088 微处理器中,数据可以存放在多个不连续的段中。这是因为 8088 采用了分段内存管理机制。
- 在 8088 微处理器中,INTA(Interrupt Acknowledge)信号用于响应外部中断请求,并读取中断向量。
- 在 8088 微处理器中,Ready 信号是由外部硬件产生的,用于控制 CPU 与外部设备之间的数据传输同步。
- Ready 信号的作用:
Ready
信号用于指示外部设备是否已准备好与 CPU 进行数据传输。- 当
Ready
信号为高电平(1
)时,表示外部设备已准备好,CPU 可以继续执行总线周期。 - 当
Ready
信号为低电平(0
)时,表示外部设备未准备好,CPU 会插入等待状态(Tw
),直到Ready
信号变为高电平。
- Ready 信号的来源:
Ready
信号是由外部硬件(如存储器或 I/O 设备)产生的。- 外部硬件根据自身的状态决定是否将
Ready
信号置为高电平或低电平。
- CPU 的响应:
- 8088 CPU 在每个总线周期的
T3
状态采样Ready
信号。 - 如果
Ready
信号为低电平,CPU 会插入一个或多个等待状态(Tw
),直到Ready
信号变为高电平。
- 8088 CPU 在每个总线周期的
- Ready 信号的作用:
- 在 8086/8088 系统中,RQ/GT 和 HOLD/HLDA 信号是与系统中其他总线主设备(如:DMA 控制器)通信的信号。
- HOLD/HLDA 信号:
HOLD
是总线请求信号,由其他总线主设备(如 DMA 控制器)发出,请求占用总线。HLDA
是总线响应信号,由 CPU 发出,表示 CPU 已释放总线,其他总线主设备可以占用总线。
- RQ/GT 信号:
RQ/GT
(Request/Grant)是总线请求/授权信号,用于在多个总线主设备之间仲裁总线使用权。RQ
是总线请求信号,由其他总线主设备发出。GT
是总线授权信号,由 CPU 发出,表示总线使用权已授予请求的设备。
- HOLD/HLDA 信号:
- 例题:IBM PC 机的 8088 处于最大模式,其总线仲载就是由(B)裁决。
- A. 非 RQ/ 非 GT
- B. 8289
- C. 8087
- D. 8288
- 解析:
- A. 非 RQ/非 GT:这是 8088 的信号线,用于请求和释放总线控制权。但它本身并不负责仲裁,而是用于与总线仲裁器通信。
- B. 8289:8289 是总线仲裁器芯片,专门用于在最大模式下管理总线仲裁。它根据设备的优先级和请求来决定哪个设备可以获得总线控制权。
- C. 8087:8087 是数学协处理器,用于浮点运算,与总线仲裁无关。
- D. 8288:8288 是总线控制器芯片,用于生成控制信号(如读/写信号),但不负责总线仲裁。
8286 芯片
8286 是 Intel 生产的一个双向数据收发器,用于在微处理器和外设或其他系统组件之间进行数据交换。它主要用于控制数据流的方向,使得数据总线能够在输入和输出状态之间切换。
- 8286 是一种 8 位双向数据收发器,主要用于 I/O 设备接口,它能够在微处理器和外设(如内存、I/O 端口等)之间传递数据。
- 双向意味着它既可以用来将数据从 CPU 发送到外部设备,也可以从外部设备接收数据传送到 CPU。
8282 芯片
8282 是 Intel 生产的一款地址锁存器,用于在计算机系统中将地址总线和数据总线分离,确保处理器能够正确地处理地址与数据。它常常被用于与处理器和其他外设(如 8255)的连接中,特别是在 8086/8088 系列处理器中。
- 8282 是一种 8 位地址锁存器,它用于将地址总线从数据总线中分离,使得处理器能够有效地访问内存和 I/O 设备。
- 它通过锁存功能(latch)在数据传输周期内将地址信号保存在内部寄存器中,避免地址信号在不同的总线周期中混乱。
中断及 8259A 可编程中断控制器
中断
- 中断向量表结构:
- 中断向量表位于内存的 0000:0000 到 0000:03FF 区域,共有 256 个中断向量。
- 每个中断向量占用 4 个字节:
- 前 2 字节存储中断服务程序的偏移地址(IP)。
- 后 2 字节存储中断服务程序所在段地址(CS)。
- 第
n
个中断向量的地址为: $\text{地址} = n \times 4$。
- 例题:内部中断的优先级通常高于可屏蔽中断(
INTR
)。但非屏蔽中断(NMI
)的优先级高于某些内部中断(如单步中断)。 - 例题:中断服务程序的代码可以存放在用户可用的内存区域,但需要满足一定的条件(如通过中断向量表正确指向,并确保内存区域的安全性)。
- 例题:在 PC/XT 机中键盘的中断类型码就是 09H,则键盘中断矢量存储在 24H - 27H。
- 例题:在 8086 微机系统中,外部设备的中断请求通常通过 8259A 管理,8259A 的中断请求输出连接到 CPU 的 INTR 引脚。
- 例题:下述中断,优先权级别最高的中断就是 (A)。
- A. NMI
- B. INTR
- C. 单步中断
- D. INTn
- 解析:
- 选项 A:NMI(非屏蔽中断)。NMI 是一种硬件中断,表示不能被屏蔽的中断。它的优先级非常高,通常用于处理如硬件故障等紧急情况。优先级:最高。NMI 无法被屏蔽,即使其他中断处于挂起状态,NMI 仍然会被立即处理。
- 选项 B:INTR(可屏蔽中断)。INTR 是普通的可屏蔽中断,它是由外部设备发起的中断,处理器可以通过设置标志位来屏蔽或允许这个中断。优先级:低于 NMI。因为它是可屏蔽的,可以被其他更高优先级的中断(如 NMI)或中断屏蔽标志(IF)屏蔽。
- 选项 C:单步中断。单步中断是一种特殊的中断类型,用于调试程序时,每执行一条指令就触发一次中断。优先级:较低。单步中断用于调试,通常其优先级较低,不会干扰正常的中断处理流程。
- 选项 D:INTn(软件中断)。INTn 是一种由程序主动触发的中断,它的优先级取决于中断向量表中的位置。它通常用来进行系统调用或其他任务。优先级:低于 NMI 和单步中断。INTn 中断可以被屏蔽,且通常是软件触发的,优先级较低。
8259A 的基本特性
- 每片 8259A 提供 8 个中断请求输入(IR0-IR7),即最多处理 8 级中断。
- 通过级联可以扩展中断级数,一片 8259A 主片最多可以级联 8 个从片。
- 主片的一个中断请求输入(如 IR2)用于接收从片的中断信号。
- 例题:3 片 8259A 级联,最多可管理 22 级中断。
- 主片的 6 个独立中断 + 从片 1 的 8 个中断 + 从片 2 的 8 个中断 = 22 个中断级。
- 例题:PC/XT 机中若对从片 8259A 写入的 ICW2 就是 70H,则该 8259A 芯片的 $IRQ_5$ 的中断矢量存储的地址就是 1D4H。
- 前五位为中断类型码,后三位为中断类型号(对应 $IR_0$)。推出 $IRQ_5$ 的中断类型号为 $75H$,乘 4 为 1D4H。
- 例题:下面就是关于可编程中断控制器 8259A 的叙述,其中错误的就是 (C)。
- A. 8259A 具有优先级管理的功能。
- B. 8259A 具有辨认中断源的功能。
- C. 8259A 具有向 CPU 提供中断向量的功能。
- D. 一片 8259A 可管理 8 级中断。
- 解析:
- A. 8259A 具有优先级管理的功能。正确:8259A 是具有优先级管理功能的中断控制器。它可以按照优先级顺序处理多个中断请求。在默认情况下,8259A 是按照固定优先级来管理中断的,但它也支持轮询优先级的方式。
- B. 8259A 具有辨认中断源的功能。正确:8259A 的一个重要功能就是能够辨认中断源。当多个外部设备发送中断请求时,8259A 会识别并区分不同的中断源(例如,$IRQ_0$ 到 $IRQ_7$),并将相应的中断请求传递给 CPU。
- C. 8259A 具有向 CPU 提供中断向量的功能。错误:虽然 8259A 能够生成中断请求并控制中断优先级,但它不直接提供中断向量。中断向量是由初始化命令字(ICW2)来设置的,它决定了中断类型码,而 8259A 本身并不生成完整的中断向量。8259A 向 CPU 提供的是中断请求信号,具体的中断向量信息通常由中断向量表提供。
- D. 一片 8259A 可管理 8 级中断。正确:单片 8259A 可以管理 8 个中断请求,分别对应 $IRQ_0$ 到 $IRQ_7$。每个中断请求都可以有不同的优先级,并且可以根据需要屏蔽或响应。
8259A 的优先权管理
在中断管理中,中断优先权的管理是一个核心。8259A 有两类确定优先权的方法:固定优先级和循环优先级。每一类中又有一些不同的实现方法。
固定优先级
这种方式下,各个中断源的优先级由它所连接的引脚编号决定,一旦连接,它的优先级就已经确定。具体有全嵌套方式和特殊全嵌套方式两种。
- 全嵌套方式(正常嵌套)是 8259A 最常用的一种工作方式。如果对 8259A 进行初始化后没有设置其他优先级方式,那么 8259A 就按全嵌套方式工作。在全嵌套方式下,中断优先权的级别是固定的,即 $IR_0$ 优先权最高,$IR_1$ - $IR_6$ 逐级次之,$IR_7$ 最低。
- 特殊全嵌套方式一般用于 8259A 级联的情况下。此时,系统中有多片 8259A,一片为主片,其他为从片。从片上的 8 个中断请求通过它的 INT 引脚连接到主片的某个中断请求输入端 $IR_i$ 上。从片上的 8 个中断请求有着不同的优先级别,但从主片看来,这些中断请求来自同一个引脚,因此属于同一个级别。假设从片工作在全嵌套方式,先后收到了两次中断请求,而且第二次中断请求有较高的优先级,那么该从片就会两次通过 INT 引脚向上一级申请中断。如果主片采用全嵌套方式,则它不会响应来自同一个引脚的第二次中断请求。而采用特殊全嵌套方式后,就会响应该请求。 系统中只有单片 8259A 时,通常采用全嵌套方式。系统中有多片 8259A 时,主片必须采用特殊全嵌套方式,从片可采用全嵌套方式。
循环优先级
这种方式下,各个中断申请具有大体相同的优先级。具体有优先权自动循环方式和优先权特殊循环方式这两种方法。
- 在优先权自动循环方式下,某一个中断源接受中断服务以后,它的优先权就自动降为最低,而与之相邻的优先级就升为最高。例如,当前 $IR_0$ 优先权最高,$IR_7$ 最低。当 $IR_4$、$IR_6$ 同时有请求时,首先响应 $IR_4$。在 $IR_4$ 被服务后,$IR_4$ 的优先权降为最低,而 $IR_5$ 升为最高。以下依次为 $IR_6$、$IR_7$、$IR_0$、$IR_1$、$IR_2$、$IR_3$。随后,在 $IR_6$ 被响应且服务后,$IR_6$ 又降为最低,$IR_7$ 变为最高,其余以此类推。8259A 在设置优先权自动循环方式之初,总是自动规定 $IR_0$ 具有最高优先权,$IR_7$ 具有最低优先权。优先权自动循环方式由编程决定。
- 优先权特殊循环方式与优先权自动循环方式仅有一处不同:在优先权自动循环方式下,一开始的最高优先权固定为 $IR_0$;而在优先权特殊循环方式下,由编程确定最初的最低优先权,从而也就确定了最高优先权。例如,编程时确定 $IR_6$ 具有最低优先权,则 IR7 具有最高优先权。
8259A 的操作命令字
8259A 可编程中断控制器(PIC) 是一个用于管理中断请求的芯片。它通过使用 操作命令字(OCW, Operation Command Word) 来配置和控制中断的行为。8259A 具有多个操作命令字来控制不同的功能,下面是 8259A 芯片的几个主要操作命令字。
初始化命令字(ICW, Initialization Command Word)
初始化命令字用于设置 8259A 的工作模式。每次启用 8259A 时,必须首先向其发送初始化命令字。ICW 的格式:
- ICW1:指定初始化模式和中断控制。
- ICW2:指定中断类型号的起始值。
- ICW3:指定主片和从片的连接方式。
- ICW4:指定工作模式和是否支持 8086/8088 模式。
ICW1 格式
1
2
3
4
D7 D6 D5 D4 D3 D2 D1 D0
| | | | | | | |
| | | | | | | |
1 0 0 0 0 0 0 0
- D7-D5:控制初始化(固定为
000
)。 - D4:选择 8259A 是否为主片(
0
为主片,1
为从片)。 - D3:是否启用级联(
0
不启用,1
启用)。 - D2-D0:指定工作模式。
ICW2 格式
1
2
3
4
D7 D6 D5 D4 D3 D2 D1 D0
| | | | | | | |
| | | | | | | |
0 0 0 0 0 0 0 0
- D7-D3:中断类型码(7 bits)。可以指定 IRQ 的中断类型号(0x00-0xFF)。
- D2-D0:常为 0,未使用。
ICW3 格式
1
2
3
4
D7 D6 D5 D4 D3 D2 D1 D0
| | | | | | | |
| | | | | | | |
0 0 0 0 0 0 0 0
- D7-D5:设置从片的 IRQ 连接(在多片级联模式下)。
- D4-D0:设置 IRQ 线连接方式。
ICW4 格式
1
2
3
4
D7 D6 D5 D4 D3 D2 D1 D0
| | | | | | | |
| | | | | | | |
0 1 0 0 0 1 0 1
- D7:指定是否使用 8086 模式(
1
为 8086 模式,0
为 8080 模式)。 - D6-D4:指定是否支持自动终止(
0
为不支持,1
为支持)。 - D3-D0:用于设置是否支持单/多中断级联。
操作命令字(OCW, Operation Command Word)
OCW 用于控制 8259A 的操作。它有多个版本,最常用的是 OCW1、OCW2 和 OCW3。
OCW1 格式
用于设置 8259A 的中断屏蔽和优先级。
1
2
3
4
D7 D6 D5 D4 D3 D2 D1 D0
| | | | | | | |
| | | | | | | |
0 0 0 0 0 0 0 0
- D7-D0:控制中断请求的屏蔽、优先级等。
- 可以设置是否屏蔽某个 IRQ,调整优先级。
OCW2 格式
用于控制中断请求的响应,例如执行中断返回。
1
2
3
4
D7 D6 D5 D4 D3 D2 D1 D0
| | | | | | | |
| | | | | | | |
0 0 0 0 0 0 0 0
- D7-D0:控制是否响应某个中断、是否重新中断等。
OCW3 格式
用于查询 8259A 的状态,如当前中断的状态。
1
2
3
4
D7 D6 D5 D4 D3 D2 D1 D0
| | | | | | | |
| | | | | | | |
1 0 1 0 0 0 0 1
- D7-D0:指定需要查询的中断请求的状态。
例子:控制字使用
OCW1 示例:如果我们希望屏蔽所有 IRQ,那么可以设置 OCW1 为:
1
OCW1 = 0xFF
OCW2 示例:当响应某个中断请求时,我们设置 OCW2:
1
OCW2 = 0x20 // 发送中断终止命令
8255A 并行接口芯片
原理结构
在 8255A 内部,有三个数据端口寄存器 A、B、C,每个端口均为 8 位,并可以设置成输入和/或输出方式,但各个端口仍有差异。
- 端口 A ($PA_0$ - $PA_7$):8 位数据输出锁存/缓冲器,8 位数据输入锁存器。
- 端口 B ($PB_0$ - $PB_7$):8 位数据 I/O 锁存/缓冲器,8 位数据输入缓冲器。
- 端口 C ($PC_0$ - $PC_7$):8 位输出锁存/缓冲器,8 位输入缓冲器(输入时没有锁存)。 应该注意,端口 C 又可以分成两部分:高 4 位和低 4 位,它们可单独用作输出控制和状态输入。端口 A、B、C 又可组成两组端口(12 位):A 组和 B 组。在每组中,端口 A 和端口 B 用作数据端口,端口 C 中的一部分用作控制和状态联络线。在 8255A 中,除了这三个端口外,还有一个控制寄存器,用于设定 8255A 的工作方式。因此 8255A 共有 4 个端口寄存器,分别用 $A_0$、$A_1$ 指定。
- 当 $A_1 = 0,A_0 = 0$ 时,表示访问端口 A。
- 当 $A_1 = 0,A_0 = 1$ 时,表示访问端口 B。
- 当 $A_1 = 1,A_0 = 0$ 时,表示访问端口 C。
- 当 $A_1 = 1,A_0 = 1$ 时,表示访问控制寄存器。
- 例题:8255 内部共有 4 个端口,即 3 个数据端口(A 口、B 口、C 口)和一个控制端口(控制寄存器),它们可由程序寻址。
- 例题:8255 的端口 C 一般用作控制或状态信息传输。
8255A 的方式控制字和置位控制字
- 控制字用于设置其端口的工作方式、输入/输出模式等,置位控制字则用于直接控制端口的状态。
- 对 8255A 的 A 组可设定成方式 0 - 方式 2,而 B 组只能设定成方式 0 和方式 1,这可以通过 8255A 的方式控制字来设置。当向 $A_0=1$、$A_1 =1$ 的端口寄存器 (即控制寄存器) 发送 $D_7 = 1$ 的控制字时,其作用为方式控制字,各位的含义如下图所示。$D_6D_5$ 用于设置 8255A 的 A 组工作方式,$D_2$ 用于设置 8255A 的 B 组工作方式。$D_4D_3$、$D_1D_0$ 为方向控制位,0 表示端口线为输出;1 表示端口线为输入。
- 当向 $A_0=1$、$A_1 =1$ 的端口寄存器(即控制寄存器)发送 $D_7 =0$ 的控制字时,其作用为置位控制字,各位的含义如下图所示,表示将端口 C 中的指定位清零或置 1。这就是说,可以对端口 C 中的任一位进行位操作。
- 例题:对 8255 的 C 口 $D_3$ 位置 1 的控制字为
0000 0111B
。
工作方式
- 8255A 有三种基本工作方式。
- 方式 0:基本的输入/输出。
- 方式 1:有联络信号的输入/输出。
- 方式 2:双向传送。
- 例题:端口 A 工作在方式 1 或方式 2 时,会使用端口 C 的
INTR
、OBF
及STB
等信号线。
方式 0:基本的输入/输出
当将 8255A 设置成方式 0 时,其端口信号线分成 4 组,分别由方式控制字的 $D_4$、$D_3$、$D_1$、$D_0$ 位控制其传送方向,当某位为 1 时,相应的端口数据线设置成输入方式;当某位为 0 时,相应的端口数据线设置成输出方式。例如,当方式控制字设置成 1000 1010B 时,端口 A 与端口 C 的低 4 位数据线设置成输出方式,端口 B 与端口 C 的高 4 位数据线设置成输入方式。特别注意,当将端口 C 的高 4 位与低 4 位设置成同一传送方向时,则端口 C 可以当作独立的端口使用,这样,8255A 就提供了 3 个独立的 8 位端口。
方式 1:有联络信号的输入/输出
当将 8255A 设置成方式 1 时,其三个端口的信号线分成了 A、B 两组,$PC_7$ - $PC_4$ 用作 A 组的联络信号,$PC_3$ - $PC_0$ 用作 B 组的联络信号。信号线的定义与方式 1 下输入和输出方式有关。但 $PC_3$、$PC_0$ 固定用作 A 组和 B 组向 CPU 发送的中断请求信号。
- 方式 1 输入:当将 8255A 的 A 组和 B 组设置成方式 1 输入时,方式控制字中的 $D_3$ 位只用于控制 $PC_6$ - $PC_7$ 的传送方向。
- 方式 1 输出:当将 8255A 的 A 组和 B 组设置成方式 1 输出时,方式控制字中的 $D_3$ 只用于控制 $PC_4$ - $PC_5$ 的传送方向。
- 8255A 与 CPU 之间的联络:8255A 与 CPU 之间可以采用中断方式联络,其 $PC_3$、$PC_0$ 分别用作 A 组和 B 组的中断请求信号。为了对中断请求信号进行管理,8255A 中专门设置了中断屏蔽触发器 $INTE_A$ 和 $INTE_B$,它们通过对端口 C 某一位的置位控制字进行控制。通过置位控制字,当对 $INTE$ 对应的端口 C 的位置位时,$INTE=1$,这时允许产生中断请求信号;当对 $INTE$ 对应的端口 C 的位清零时,$INTE=0$,这时不允许 (屏蔽) 产生中断请求信号。
- 例题:对 8255 的端口 A 工作在方式 1 输入时,C 口的 $PC_6$、$PC_7$ 一定为空闲的。
- 例题:8255 工作在方式 1 的输出时,OBF 信号表示输出缓冲器满信号。
- 例题:当 8255 的 PA 口方式 1 输出时,若外设有负脉冲回答, 则 PC3 定会上升为高电平。
方式 2:双向传送
8255A 的 A 组可以设定成方式 2,$PC_6$ - $PC_7$ 用作输出的联络信号,$PC_4$ - $PC_5$ 用作输入的联络信号,$PC_3$ 仍用作中断请求信号。