Intel 8086

维基百科,自由的百科全书
跳转至: 导航搜索
Intel 8086 微處理器
Intel 8086 晶粒

8086是由英特爾公司於1976年开始設計,1978年年中发布的Intel第一款16位微處理器,同时也是x86架構之開端。随后于1979年,又推出了Intel 8088,它在芯片的外部接口使用8位数据总线,成为8086的一个低成本的简化产品。而最初的IBM PC使用8088微处理器。

历史[编辑]

背景[编辑]

1972年,Intel发布了8008微处理器——世界上第一款8位微处理器。8008微处理器有18个引脚,其中地址总线使用了14个引脚,并且与8位数据总线复用引脚。指令集源自是Datapoint公司为计算机的CRT-键盘终端设计的但相当通用的指令集。当时英特尔还是一家生产DRAM为主业的公司,缺乏这方面的技术储备。

1974年,Intel发布了8080微处理器,被公认是第一款真正可用的微处理器。8080的芯片封装采用40个引脚,其中8个数据总线引脚、16个地址总线引脚都是专用的,因此数据总线与地址总线可以并行工作。8080的扩展后的指令集在源代码级别上向前兼容8008指令集。

1975年,Intel发布了第三款8位微处理器——8085。采用了新的制造工艺,简化了输入电压引脚的数量。同一时期还有Motorola 6800(1974),Microchip PIC16X(1975),MOS Technology 6502(1975),Zilog Z80(1976),and Motorola 6809(1978),等8位微处理器。在8位微处理器市场竞争中Z80最为成功。

第一种x86设计[编辑]

8086项目起始于1976年5月,是英特尔公司当时更为看重的16位的iAPX 432微处理器的备份项目。8086一方面要与Motorola, Zilog, National Semiconductor等公司的16位、32位微处理器竞争市场份额,另一方面也是对Zilog Z80在8位微处理器市场上的成功的回击。由于采用了与8085微处理器近似的微体系结构与物理实现工艺,8086项目进展相当快。

8086微处理器被设计为在汇编源程序上向前兼容8008, 8080, 8085等微处理器。指令集与编程模式是基于8080微处理器,但指令集做了扩展以完全支持16位计算。

新增加的指令包括:完全支持有符号整数、段基址+偏移量寻址、类似于Z80的自重复操作、直接支持嵌套的ALGOL类语言如Pascal或PL/M、微码实现的乘法除法指令、以及更好支持与协处理器(8087或8089)和多处理器系统的总线结构.

第一版的指令集与高层的体系结构的设计仅用了3个月。在没有CAD工具的时代,4名工程师与12名布线绘图员平行工作,用了2年多的时间才把8086的高层设计实现为可运行测试的产品。这在当时算是很快的研发速度。

8086是微码与逻辑电路的混合实现,使用了大约20,000个晶体管(算上所有的ROM可编程逻辑阵列为29,000个晶体管).芯片面积为33 mm²,制造工艺为3.2 μm.

8086体系结构由Stephen P. Morse设计,并在最后定案时得到Bruce Ravenel(8087体系结构设计者)的帮助。逻辑设计者是以Jim McKevitt与John Bayliss为首的硬件开发工程师团队。项目经理William Pohlman.迄今8086的指令集仍然是PC机与服务器的基本指令集。

细节[编辑]

8086引脚的功用,在min与max模式下有所不同
Main registers
AH AL AX(primary accumulator)
BH BL BX(base, accumulator)
CH CL CX(counter, accumulator)
DH DL DX(accumulator, other functions)
Index registers
SI Source Index
DI Destination Index
BP Base Pointer
SP Stack Pointer
Status register
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 (bit position)
- - - - O D I T S Z - A - P - C Flags
Segment register
CS Code Segment
DS Data Segment
ES ExtraSegment
SS Stack Segment
Instruction pointer
IP Instruction Pointer
The 8086 registers

总线与操作[编辑]

所有的内部寄存器、内部及外部数据总线都是16位宽,因此是完全的16位微处理器。20位外部地址总线,因此物理寻址空间为1MiB (即220 = 1,048,576).由于内部寄存器都是16位,对1M地址空间寻址时采取了段寻址方式。8086的封装采用40引脚的双列直插(dual in-line),数据总线与地址总线复用了前16个引脚。16位的I/O地址,因此独立的I/O寻址空间为64KiB (即216 = 65,536).由于8086内部的地址寄存器是16 位宽,因而最大线性寻址空间为64 KiB.使用超过64 KiB内存空间的程序设计时,需要调整段寄存器(segment registers)。直到32位的80386出现之前,8086的这种段寻址相当不便.

8086芯片封装的8个控制引脚在minmax下有不同功能。"min"模式是使用单处理器的小型计算机系统,"max"模式是使用多处理器的中到大型计算机系统。

寄存器与指令[编辑]

8086有8个16比特的寄存器,包括栈寄存器SP与BP,但不包括指令寄存器IP、控制寄存器FLAGS以及四个段寄存器。AX, BX, CX, DX,这四个寄存器可以按照字节访问;但BP, SI, DI, SP,这四个地址寄存器只能按照16位宽访问。

8086以80808085(它與8080有汇编語言上的原始碼相容性)的設計為基礎,擁有類似的暫存器集合,但是擴充為16位元。总线接口單元(Bus Interface Unit)透過6位元組預存(prefetch)的貯列(queue)将指令送给執行單元(Execution Unit),所以取指令和執行是同步的-一種流水线的原始形式(8086指令長度變化從1到6位元組)。

8086有四個完全一样的16位元暫存器,但也能够當作八個8位元暫存器來存取;以及四個16位元索引暫存器(包含堆栈索引)。数据暫存器通常由指令隱含地使用,針對暫存值需要複雜的暫存器配置。它提供64K 8位元的輸出輸入(或32K 16位元)埠,以及固定的向量中斷。大部分的指令只能夠存取一個記憶體位址,所以其中一個運算子必須是一個暫存器。運算結果會儲存在運算子中的一個。

8086有4個記憶體區段(segment)暫存器,可以通过索引暫存器來設定。區段暫存器可以讓CPU一种当时是全新的方式存取多达1MB之記憶體。在現今有區段的處理器中,8086把區段暫存器左移4位元然後把它加上去寻址。这通常被認為是一個不太好的設計,因為这么做會讓各區段有重疊。儘管這樣對于汇编語言而言会显得有用——因为可以充分控制區段,但同时却使高级語言中的指针(像是C程式語言)使用變得困難。它降低了指针的高效率,且有可能產生兩個指向同一個地方的指標擁有不同的位址。更壞的是,這種方式產生要讓記憶體擴充到大於1MB的困難。而80286的寻址方式改變讓記憶體擴充較有效率。

由于8位机(如Intel 8008)时代沿袭下来的紧凑编码,大多数指令虽然有两个源操作数(operands)及一个输出结果,但单条指令至多使用两个地址,因此运算结果被存入一个源操作数中。且最多只能有一个内存操作数,另外的操作数是寄存器或立即数。内存操作数也可以用于存储指令的输出结果。8位微处理器的指令集不能把输出结果直接保存在内存操作数中,因此8086指令集的如此设计大大提高了代码密度(code density)。

相比与8080或8085,8086有更强的寄存器通用性,但比起典型的小型计算机来说仍有很大不如。8086的某些指令隐式使用某些寄存器。比起更为规则的16- 或32-位处理器如PDP-11, VAX, 68000,等等,8086的寄存器分配特性使得编译器的工作更为复杂;另一方面,比起半现代化的但广为使用的8位微处理器如6502, 6809,或8085,编译器生成代码就容易太多了.

8086有64 KiB的字宽为8位的(或32K个宽度为16位的)I/O寻址空间.

栈的长度最大为64 KB(一个段) ,8086硬件支持栈顶由高地址向低地址生长。入栈、弹栈的数据单元长度为2字节。栈顶位置由寄存器的组合SS:SP给出.

共有256 个中断,包括硬件中断与软中断。中断可以嵌套,使用栈来保存中断返回地址。

8086增加了一些8080与8085所没有的新指令,用于更好地支持PascalPL/M的高级程序设计特性;如push mem-op, ret size, (其它一些指令如push immed and enter,在随后的80186, 80286, and 80386中陆续增加.)

标志寄存器[编辑]

8086有一个16位宽的标志寄存器FLAGS.其中9个比特是被使用的,另外7个比特保留未用。具体是:进位标志CF、奇偶标志PF、辅助标志AF、为零标志ZF、符号标志SF、追踪标志TF、中断允许标志IF、方向标志DF、溢出标志OF。

内存分段[编辑]

在Intel的8位、16位处理器中,由于寄存器的宽度为8或16比特,而地址总线的宽度一般是要大于寄存器的宽度,所以为了能访问整个地址空间,需要采取特殊的寻址计算——分段寻址。从80386开始的32位微处理器,地址总线宽度也是32比特,可以视作扁平(flat)地址空间,不再需要分段寻址。

8086的分段寻址,是指一个物理地址由段地址(segment selector)与偏移量(offset)两部分组成,长度各是16比特。其中段地址左移4位(即乘以16)与偏移量相加即为物理地址。例如,06EFh:1234h,表示段地址为06EFh,偏移量为1234h,物理地址为06EF0h + 1234h = 08124h。在计算物理地址时如果发生上溢出,8086处理器舍弃进位。例如,FFFFh:0010h所对应的物理地址为00000h.

一个20位的物理地址对应着4096个不同的"段地址:偏移量"的组合。这是因为,偏移量的最低4位对应于物理地址的最低四位,而偏移量的高12位共有4096个取值。

段地址所对应的物理地址的粒度是16字节(=24),称之为paragraph。

段地址确定后,偏移量的取值最多为64KiB(=65536),这就是分段寻址的最大的线性地址空间。实际上在8086处理器上,操作系统分配的线性地址空间可以是不大于64KiB的任意数量。程序可以自由访问整个物理内存空间,操作系统没有任何权限限制或监管(supervision)。

8086处理器有20根地址总线引脚(pins),因此物理内存空间最大为220=1MiB=1,048,576字节。这还包括了IO内存。因此使用8086处理器的计算机的主存的容量少于1MiB,最常见的主存容量是640KiB。

由于X86指令集的向后兼容原则,计算物理地址时,段地址左移4位被所有后继支持实模式的X86处理器所继承。80286是使用24位宽地址总线的16位微处理器,如果要在整个224=16MiB物理存储空间寻址,就必须采用其它方式,即保护模式寻址,这时16位的段地址是指向段描述符表(segment descriptors table)的一个包含24位基地址的条目,基地址加上16位偏移量即为24位的物理地址。

在8086上运行的编译器,一般支持两种C语言的指针:近指针(near)与远指针(far)。近指针是16位的地址偏移值,隐式与程序的代码段地址或数据段地址结合使用以确定物理地址。远指针是32位的“段地址:偏置量”成对出现,用以确定20位的物理地址。某些编译器支持“巨指针”(huge),类似于远指针。但巨指针的地址运算是线性20位;而远指针的地址运算在16位偏移值溢出时不影响段地址部分,因此远指针的线性部分是16位。

为了避免对大量的指针、数据结构、函数指出是“近”还是“远”,编译器提供了内存模式(memory model)给出了缺省的内存访问方式:

  • 微模式tiny数据段代码段共用不超过64K内存空间,编译为.com可执行文件;
  • 小模式small数据段、代码段各用最多64K内存共空间;
  • 紧凑模式compact数据段> 64K;
  • 中模式medium代码段> 64K;
  • 大模式large代码段数据段都> 64K;
  • 巨模式huge单个数组> 64K。

预编译库对不同的内存模式要分别编译为相应版本。

移植老的程序[编辑]

8位机上的程序可以不考虑段地址直接以.com可执行文件以“微模式”在8086上运行。这是当时8086与MS-DOS作为新平台取得市场成功的关键原因——大量已存的CP/M应用程序能很快得到利用。

性能[编辑]

外部总线作为数据与地址的复用,降低了CPU的性能。取16比特或8比特数据需要4个时钟周期。指令的长度为1-6个字节,取指令与执行是并发完成的。CPU内的总线界面单元把取到的指令保存在6字节的预取队列中。

典型指令的执行时间
(时钟周期)[1]
instruction register-register register immediate register-memory memory-register memory-immediate
mov 2 4 8+EA 9+EA 10+EA
ALU 3 4 9+EA, 16+EA, 17+EA
jump register => 11 ; label => 15 ; condition,label => 16
integer multiply 70~160(depending on operand data as well as size)plus EA
signed integer divide 80~190(depending on operand data as well as size)plus EA
  • EA = 计算有效地址的时间,5到12周期.
  • 用时为最好的情形,依赖于预取状态,指令对齐,及其它因素.
Intel 8088(8086的一个变种)简化模块图; 1=主寄存器; 2=段址寄存器与IP寄存器; 3=地址加法器; 4=内部地址总线; 5=指令队列; 6=控制单元; 7=总线界面; 8=内部数据总线; 9=ALU; 10/11/12=外部数据/地址/控制总线

8086涉及内存访问的指令,包括跳转(jump)指令需要比80808085更多的时间,原因在于:

  • 取指令与执行指令是松散耦合,对于跳转与随机数据访问没有特殊措施,效率较低.
  • 没有专门的地址计算部件,只能用主ALU,虽然有专用的段地址 + 偏移地址的加法器
  • 外部地址总线与数据总线是多工复用,与8位处理器相比要多用33~50%的总线周期

8086的后继处理器的内存访问性能大大增强了。80186 and 80286有专门的地址计算硬件,节约了很多时间周期。80286的外部地址总线与数据总线是分开各自专用的。

浮点[编辑]

8086/8088可以连接上专用的数学协处理器以增加浮点计算性能。标准的数学协处理是Intel 8087,执行80位浮点数运算。

使用8086的微電腦[编辑]

第一個以8086為基礎的商業微電腦是Mycron2000。

IBM Displaywriter文字處理機也使用8086。在大部分顯要的所有微處理器中,IBM PC使用了更窄的記憶體總線版本的8086,也就是Intel 8088。 8086CPU結構上的一個重要特點是分為二大部分,即總線接口單元BIU和執行單元EU,其中BIU負責外部信息交換,EU負責指令執行,二者合理分工、並行工作,工作效率比此前的CPU明顯提高,常稱之為流水線結構。

外部連結[编辑]

参考文献[编辑]

  1. ^ Microsoft Macro Assembler 5.0 Reference Manual. Microsoft Corporation. 1987. "Timings and encodings in this manual are used with permission of Intel and come from the following publications: Intel Corporation. iAPX 86, 88, 186 and 188 User's Manual, Programmer's Reference, Santa Clara, Calif. 1986." (Similarly for iAPX 286, 80386, 80387.)

Article based on Intel 8086 at FOLDOC,used with permission.