下面是 Intel 8086CPU
的介绍: (1) 16位微处理器; (2) 采用高速运算性能的 HMOS
工艺制造,芯片上集成了2.9万只晶体管; (3) 使用单一的 +5V
电源,40
条引脚双列直插式封装; (4) 时钟频率为 5MHz~10MHz
,基本指令执行时间为0.3ms~0.6ms
; (5) 16根数据线和 20根地址线,可寻址的地址空间达 1MB
(毕竟 16根地址线只可以寻址 64KB,太小了) ; (6) 8086可以和浮点运算器、输入/输出处理器或其他处理器组成多处理器系统,从而极大地提高了系统的数据吞吐能力和数据处理能力; (7) 8086微处理器从功能上可以划分为两个逻辑单元:执行部件 EU
(Execution Unit) ;总线接口部件 BIU
(Bus Interface Unit) 。 (8) 8086微处理器的寄存器结构:8086可供编程使用的有 14个 16位寄存器,按其用途可分为3类:通用寄存器;段寄存器;指针和标志寄存器。
8088
的内部结构与 8086
基本相同,不同点: (1) 8086的指令队列为 6字节,8088为 4字节; (2) 8086 BIU的外部数据总线为 16位,而8088为 8位。 可以说 8088
是 8086
的偷工减料版本,但是它卖得多,成为了第一代PC机的事实标准。这里学的也基本是上是以8088为蓝本。
内部寄存器存放运算中的操作数、操作数地址、中间结果及最后结果。存取速度比存储器快许多。编程时须了解各寄存器的功能和用法。8088
与 8086
内部寄存器完全相同,下面的 14 个寄存器必须记住。
16位数据寄存器 AX
、BX
、CX
、DX
,存放 16位数据信息或地址信息。这 4 个寄存器最大的特点在于,每个 16 位寄存器也可分成 2 个 8位寄存器来使用:AL
、BL
、CL
、DL
,AH
、BH
、CH
、DH
。只能存放 8位数据,不能存放地址。
数据寄存器也可有专门用途。例如:
AX
(Accumulator) 累加器,在编程中用得最多;AX
、AH
和AL
在乘、除法中有专门用途;BX
(Base) 基地址寄存器,可存放偏移地址;CX
(Count) 计数寄存器,在循环操作时作计数器用,用于控制循环程序的执行次数;DX
(Data) 数据寄存器,在乘、除法及I/O端口操作时有专门用途。
地址指针和变址寄存器 SP
、BP
、SI
、DI
以及基址寄存器 BX
,可与段寄存器配合使用,一起构成内存的物理地址。
- 堆栈指针
SP
(Stack Pointer) 和基址指针BP
(Base Pointer) 可与堆栈段寄存器SS (Stack Segment) 联合使用,用于设置或访问堆栈段。 - 源变址寄存器
SI
(Source Index) 和目的变址寄存器DI
(Destination Index) 具有通用寄存器的功能,通过SI
、DI
以及基址寄存器BX
,可在内存中灵活寻找存储器操作数。在字符串运算中,可由DS:SI
指向源串数据,ES:DI
指向目的串,实现串数据传送等操作。
这些寄存器存放段内地址的偏移量 (Offset) ,与段寄存器配合后,可实现灵活的寻址。主要在堆栈操作、字符串操作和访问存储器时使用。
3. 段寄存器8086/8088
用分段技术寻址(地址是相对于某个段的基地址的偏移地址),用一组段寄存器将 1MB
空间分成若干逻辑段,每段 64KB
,段内设偏移地址。毕竟,8086是 16位的CPU,又需要访问到 1MB
的空间,所以需要 4 只“眼睛”。
8086/8088
内部设置了4个16位的段寄存器,段寄存器存放各段始址的高 16位,称为段基地址或段基址:
- 代码段寄存器
CS
(Code Segment) (和后面的IP
寄存器一对) ; - 数据段寄存器
DS
(Data Segment) (和前面的SI,DI
配对) ; - 堆栈段寄存器
SS
(Stack Segment) (和前面的SP
、BP
一组) ; - 附加段寄存器
ES
(Extra Segment) (和前面的SI,DI
配对)
但是仅仅只有这 4 只“眼睛”,就只能看到 4*64kb=256kb
的地址空间,为此我们需要转动一下这些“眼睛”,将段基址与段内偏址 Offset
(SP,BP
、SI,DI,BX
)组合起来,就可以形成 20 位物理地址。
IP
指向将要执行的下条指令的偏移地址。下条将要执行指令的地址由 CS:IP
(即代码段的IP偏移地址)决定。程序运行时,每当 CPU
从代码段中取出 1字节指令代码后,IP
就自动 + 1 。
用户程序不能对IP进行存取,只能由 BIU
自动修改。
标志寄存器 FLAGS
设置了 9 个标志位,格式:
CF
、PF
、AF
、ZF
、SF
和OF
为状态标志,用来表示指令执行后的结果或状态特征,转移指令根据它们来控制程序走向;TF
、IF
和DF
为控制标志,由程序设置或清除。
- 进位标志
CF
(Carry Flag)
- 最高位向前一位产生进位或借位时,
CF=1
,否则CF=0
。只有在两个无符号数进行加减
运算时,CF标志才有意义; - 移位操作将影响CF标志;
- 执行
STC
指令可使CF置 1 11 ,CLC
指令使CF清 0 00 ,CMC
指令使CF标志取反。
- 奇偶校验标志
PF
(Parity Flag)
- PF标志也称为偶标志。
- 若本次运算结果低
8
位有偶数个1
(如01101010B
) ,则PF=1
,否则PF=0
。
- 辅助进位标志
AF
(Auxiliary Flag)
- AF标志也称为半进位标志。
- 在
8
位加减运算中,低4位向高4位有进位或借位,AF=1
,否则AF=0
; - 只有在BCD数运算时AF才有意义。利用调整指令可对运算结果进行调整。
- 例 设
AL=BCD数14
,BL=BCD数9
,用减法指令求两数之差。14-9=5
,但是BCD数相减后为[0000 1011]=11
,需要调整为BCD数0000 0101 = BCD数5
。 - 低4位向高4位有借位,
AF=1
,需用减法调整指令DAS
进行“减6”调整。 - BCD数进行加法运算时,用加法调整指令
DAA
,自动进行“加6”调整运算。
-
零标志
ZF
(Zero Flag) :运算结果为0,则ZF=1
,否则ZF=0
。 -
符号标志
SF
(Sign Flag) :也称负标志。运算结果最高位为1,则SF=1
,表示该数为负数;否则SF=0
,表示该数为正数。 -
溢出标志
OF
(Overflow Flag)
-
带符号数运算时,结果超出了机器能表示的范围,称为溢出。溢出时
OF=1
,否则OF=0
。 -
字节数据的范围为
-128~+127
,字数据范围为-32768 ~ +32767
。 -
OF
标志只有在带符号数运算时才有意义。 -
例:两个带符号数 (
+105+50=155
) 相加,如何影响各标志位?如果把数当成无符号数,则不考虑SF和OF标志,运算结果为155,是正确的。假如两个无符号数相加后
CF=1
,则进位也应算作结果,不能丢掉。 这里是带符号数的加法,运算后各标志位状态如下:CF=0
,无进位;PF=0
,结果低8
位有奇数个 1 11;AF=0
,非BCD数运算,无半进位;ZF=0
,结果非 0 00;SF=1
,结果为负数;OF=1
,带符号数运算,溢出 (两个正数相加,结果变成了负数 − 101 -101−101)
-
溢出与自然丢失与进位之间的区别。求
-50
和-5
之和:运算结果:两数之和为
-55
,SF=1
(负数) ,OF=0
(无溢出) ,结果正确。虽然CF=1
,但它会“自然丢失”,带符号数相加时, 判断CF=1?
是没有意义的。 -
8位寄存器或存储器位数不够用时,可用16位运算,数字较大时还可采用双字运算。
什么数是正数、负数、带符号数、无符号数和BCD数?实际由编程人员确定; (1) 如果你把参加运算的数当成带符号数,运算后可去查 SF、OF
标志; (2) 如果当成无符号数,运算后就去查 CF
标志; (3) 如果当成BCD数,运算后就去查 AF
标志; (4) 不管参加运算的数是什么类型,都可查 ZF、PF
标志。
- 陷阱标志
TF
(Trap Flag)
- 若
TF=1
,CPU处于单步工作方式。每执行完一条指令,自动产生一次单步中断,将寄存器、存储器等内容显示在屏幕上。程序员可查看本条指令执行后的结果,以便逐条检查指令执行结果。 - 若
TF=0
,则程序正常运行。
- 中断标志
IF
(Interrupt Flag)
IF=1
时,允许CPU响应可屏蔽中断;IF=0
时,禁止响应该中断。- 执行
STI
指令可使IF置1,CLI
指令使IF清0。
- 方向标志
DF
(Direction Flag)
- 控制字符串操作指令中地址指针变化的方向。
- 若
DF=0
,串操作时地址指针SI、DI
自动递增;若DF=1
,SI、DI
自动递减。 CLD
指令使DF=0,STD
指令使DF=1。
AD 15 ~ AD 0 :地址/数据总线(Address/Data),双向、三态、分时复用。
CPU
访向内存或I/O设备时,先在AD
线上传送地址信号,并锁存起来;再传送数据信号,在时间上把地址/数据信号分开。- 8088只需传送 8 位数据,只有 AD 7~ AD 0 为地址/数据线,A 15~ A 8 上只传送地址信号(Address)。
地址/状态线,先传送高 4
位地址 A 19 ~ A 16 ,后传送状态信号 S 6 ~ S 3。
- 在
T1
周期用作高4
位地址A19~A16
,存储器操作时需锁存;I/O
操作时,高4位无效,仅用A15~A0
寻址。 - 在
T2~T4
周期,用作状态信号S6~S3
。其中S6=0
;S5=1
允许可屏蔽中断,S5=0
禁止;S4S3
指出当前使用的段寄存器:
读信号。当 RD=0 时,允许CPU从存储器或I/O端口读出数据。
4. WR (Write)写信号。当 WR=0 时,允许CPU向存储器或I/O端口写入数据。
5. M/IO (Memory/Input and Output)存储器或I/O端口控制信号。它为高电平时访问内存,低电平时访问I/O端口。8088该引脚为 M/IO=1 访I/O端口,M/IO=0 访存。
6. CLK时钟信号,是外部时钟产生器8284A提供的基本定时脉冲。
- 8086:fCLK=5MHz
- 8086-1:fCLK=10MHz, 8086-2:fCLK=8MHz
复位信号,至少要维持4个时钟周期。
- 复位后CPU停止所有操作,总线无效;使
DS、ES、SS、FLAGS、IF
清0,CS: IP=FFFF: 0000H
; 使指令队列变空,禁止中断。 - 复位结束后,CPU执行重启动过程。
1) INTR (Interrupt Request)
可屏蔽中断请求信号。当 INTR=1
时,若 FLAGS
的 IF=1
,则允许CPU响应可屏蔽中断;若 IF=0
,则不能响应。
2) NMI (Non-Maskable Interrupt)
不可屏蔽中断请求信号。这类中断不能用软件屏蔽,也不受IF标志的影响。
3) INTA ‾ \overline {\text{INTA}}INTA (Interrupt Acknowledge)
中断响应信号。是在CPU响应外部可屏蔽中断请求后,向外设发出的回答信号。
9. HOLD (Hold Request)/HLDA (Hold Acknowledge)总线保持请求/总线保持响应信号,这两个信号在 DMA
操作时使用。
地址锁存允许信号。
11. DT/ R ‾ \text{DT/}\overline \text{R}DT/R (Data Transmit/Receive)数据发送/接收信号,用来控制数据传送的方向:
- DT/R=1 ,CPU用写操作向外部发送数据;
- DT/R=0 ,CPU读取外部传送过来的数据。
数据允许信号。DEN=0 才允许CPU发送或接收数据。
13. READY准备就绪信号。
READY=0
,被访问的存储器或I/O端口还未准备好,T3
周期结束后自动插入等待周期Tw
。READY=1
,已准备好,则进入T4
周期,完成数据传送。
测试信号。
15. 最小模式/最大模式复用信号图2.1中,24~31
引脚为最小/最大模式复用信号,下面是带()的最大模式信号。
1) QS1、QS0 (Instruction Queue Status)
指令队列状态信号。指示CPU中指令队列的当前状态组合功能:
2) S2 ~ S0 (Bus Cycle Status)
总线周期状态信号。CPU将它们传送给8288总线控制器,经8288译码后产生CPU的总线周期类型信号:
3) LOCK
总线封锁信号。
4) RQ/GT1、RQ/GT2 (Request/Grant)
总线请求信号输入/总线请求允许信号输出。
16. BHE/S7 (Bus High Enable/Status)高 8
位总线允许/状态信号,它用在8086中。低电平时,高8位数据总线D15~D8有效。状态位S7始终为1。
8088最小模式信号,相当于最大模式下的 S0
信号。IO/M,DT/R,SS0 组合产生的总线类型与 S2 ~ S0 组合产生的信号一样,见表2.3。
最小/最大模式选择信号。
- MN/MX 接
+5V
,CPU工作于最小模式,组成单处理器系统。 - MN/MX 接地,CPU工作于最大模式,支持构成多处理器系统。
Vcc 电源输入,为CPU提供 +5V
电源。GND
是接地引脚。
这些引脚中很多复杂的我们用不到,用到的以后会写。
三、8086的存储器组织CPU
的工作方式:8086/8088
只能工作于实模式,仅能访问 2^20 =1MB 存储器。实模式下,只能从能被 16整除的那些单元开始分段。
80286
及以上CPU可工作于实模式和保护模式。在保护模式下,寻址范围为
- 80286 :寻址 2^24=16MB 内存
- 80386: 寻址 2^32=4GB 内存
8086/8088
有 20 根地址线,寻址 2^20 = 1MB 单元,地址范围 00000~FFFFFH
。每个单元有 1个绝对地址,即物理地址,CPU应先确定物理地址,才能存取该单元。
1MB
内存空间分成多个逻辑段,每段最大 2^16=64KB,段内地址连续。各段相互独立,可连续排列,也可部分重叠或完全重叠。
用两个16位寄存器来形成 20位地址,形式为:段地址:偏移量
。这也称为逻辑地址,段地址也称为段基地址。
-
段基地址定义任何
64KB
存储器的起始地址,偏移量在64KB
存储器中选择任一单元。(段基址是实际物理地址的高16位) -
由逻辑地址转换为物理地址的公式:
20位物理地址 = 段基地址 * 16 + 16位偏移量
。即段寄存器中的 16位数自动左移 4 位 + 16位偏移量(出现在程序中的地址量)就形成 20 位物理地址。由BIU
的地址加法器∑ 来计算物理地址。
设段地址:偏移地址=1234:0025H
,形成 20位物理地址 12365H
的过程: 如何用段基地址和偏移地址形成一个段,由偏移地址来选择段中的一个存储单元。
例:设某个段寄存器的内容为 3000H
,则该段的起始地址和末地址各是什么?如果偏移地址 OFFSET = 500H
,则该单元的物理地址是多少? 分析:根据物理地址的形成方法可知:
- 段起始物理地址为
3000H
×16 = 30000H
; - 段结束物理地址为
3000H
×16 + FFFFH =3 FFFFH
; - 偏移地址
OFFSET=500H
时,该单元的物理地址为3000H
×16 + 500H = 30500H
一个物理地址可以由不同的逻辑地址来形成。比如:一个存储单元的物理地址为12345H,它可以由哪些逻辑地址形成? 分析:
1200:0345H
1234:0005H
1232:0025H
- …
这说明从 12000H
单元偏移 345H
单元和从 12340H
偏移 5
个单元等,均指向同一个内存单元。
CS
和 IP
组合寻址代码段下一条要执行指令的字节单元;SS
和 SP,BP
组合寻址存储器堆栈段中的数据;DS
和 BX
、SI
、DI
组合寻址数据段中的 8位或 16 位数据;ES
和 DI
组合寻址目的串地址。
通过段超越前缀可以对某些隐含规则进行修改。
3.1.3 堆栈的设置和操作令 SS=2000H
,SP=1300H
为栈顶地址。堆栈范围为 2000:0000H
~ 2000:(1300H-1)
, 即 20000H ~ 212FFH
。 由于高位数据存放在高地址,低位数据存放在低地址,数据向上向低位地址增长。所以
SS
为堆栈基地址, SP
栈顶指针指向低地址。
- 最开始,
SS=SP
,栈底就是栈顶; - 当
SP=0H
时,说明SP
指向了堆栈段的栈顶,整个堆栈满了。
CPU
工作于最小模式时,送到存储器和I/O接口的所有信号都由CPU产生。 工作于最大模式时,某些控制信号由8288总线控制器产生 (产生系统总线信号,基本作用是译出/S0,/S1和/S2三个状态信号) 。最大模式主要用于包含数值协处理器 (Numeric Data Processor, NDP) 8087的系统中。