Intel处理器从 Intel 8086 处理器到最新的14th Intel® Core® i9 、14th Core® i7 Quad 以及 Intel Xeon 处理器 5300 和 7300 系列。在Intel的维护下,为 1978 年发布的处理器创建的目标代码仍能在最新的 Intel 64 和 IA-32 架构系列处理器上运行。
Intel处理器之所以做到如此强大的兼容性,就不得不说说Intel的处理器体系架构了。
目前,Intel处理器体系上大体分为IA-32和Intel 64两种,IA-32体系结构被32位处理器所使用,Intel 64体系结构被64位处理器所使用。(Intel 64在早期曾起名IA-32e,后因64位AMD处理器的架构体系被命名为AMD64,Intel才将IA32e改名Intel 64)
下面我们来看第一个具有代表意义的,被称作IA32鼻祖的cpu——Intel 8086
Intel 8086是Intel公司于1978年发布的第一款16位微处理器,Intel 8086的运行模式被称作实模式
(Real Mode),它奠定了x86架构的基础。x86架构后来发展成了IA-32(32位架构)和Intel 64(64位架构),并且至今仍在Intel的现代处理器中使用。
Intel 8086参数如下:
参数 | 规格 |
---|---|
处理器类型 | 16位 |
时钟速度 | 4.77 MHz至10 MHz |
地址总线 | 20位,支持1 MB的内存寻址空间 |
数据总线 | 16位 |
指令集架构 | x86架构 |
寄存器 | 14个16位寄存器 |
指令周期 | 2至12个时钟周期(视指令而定) |
封装类型 | 40引脚DIP(双列直插封装) |
最大内存 | 1 MB(通过20位地址总线寻址) |
指令集 | 支持x86指令集 |
因为只有20根地址总线,所以处理器可以直接访问只有1 MB的内存地址空间。实模式采用段:偏移的内存寻址方式,通过将16位段寄存器与16位偏移值相加,生成20位的物理地址
Intel® 64 and IA-32 Architectures Software Developer's Manual
手册第2.1.1节中写道:
The IA-32 architecture family was preceded by 16-bit processors, the 8086 and 8088. The 8086 has 16-bit registers and a 16-bit external data bus, with 20-bit addressing giving a 1-MByte address space. The 8088 is similar to the 8086 except it has an 8-bit external data bus. The 8086/8088 introduced segmentation to the IA-32 architecture. With segmentation, a 16-bit segment register contains a pointer to a memory segment of up to 64 KBytes. Using four segment registers at a time, 8086/8088 processors are able to address up to 256 KBytes without switching between segments. The 20-bit addresses that can be formed using a segment register and an additional 16-bit pointer provide a total address range of 1 MByte.
这是作者自己翻译的内容,仅供参考:
IA-32 架构家族的前身是 16 位处理器 8086 和 8088。8086 具有 16 位寄存器和 16 位外部数据总线,使用 20 位寻址,提供 1 MB 的地址空间。8088 类似于 8086,但其外部数据总线为 8 位。8086/8088 处理器引入了分段技术。通过分段,16 位的段寄存器包含指向最多 64 KB 内存段的指针。使用四个段寄存器,8086/8088 处理器可以在不切换段的情况下寻址最多 256 KB。通过段寄存器和额外的 16 位指针,可以形成 20 位地址,提供总计 1 MB 的地址范围。
例如数据保存在内存地址0x1234D的地方,那么我们可以这样获取该数据:
mov ax, 1234H
mov ds, ax 设置段地址
mov ax, 000DH
mov bx, [ax] 默认使用ds段寄存器,此时地址为DS:AX即1234:000D
Intel 8086处理器包含14个16位寄存器,分为通用寄存器、段寄存器、指针寄存器和标志寄存器。
类别 | 寄存器 | 描述 |
---|---|---|
通用寄存器 | AX | 累加器寄存器,用于算术和逻辑操作,可分为AH(高8位)和AL(低8位)。 |
BX | 基址寄存器,通常用于存储内存地址,可分为BH和BL。 | |
CX | 计数器寄存器,常用于循环计数和字符串操作,可分为CH和CL。 | |
DX | 数据寄存器,用于I/O操作和乘法、除法运算,可分为DH和DL。 | |
段寄存器 | CS | 代码段寄存器,存储当前执行代码段的基地址。 |
DS | 数据段寄存器,存储数据段的基地址,通常用于数据存储。 | |
SS | 堆栈段寄存器,存储堆栈段的基地址,用于栈操作。 | |
ES | 附加段寄存器,通常用于字符串操作,作为附加的数据段。 | |
指针和索引寄存器 | SP | 堆栈指针寄存器,指向当前堆栈顶端,用于栈操作。 |
BP | 基址指针寄存器,通常用于访问堆栈中的数据,尤其是函数参数。 | |
SI | 源变址寄存器,常用于指向源数据,特别是在字符串操作中。 | |
DI | 目的变址寄存器,常用于指向目的数据,在字符串操作中用作目的地址。 | |
标志寄存器 | Flags | 标志寄存器,包含状态标志和控制标志,如进位标志(CF)、零标志(ZF)、符号标志(SF)、溢出标志(OF)等。 |
虽然Intel 8086处理器所使用的实模式具有简单的内存管理特性,不支持内存保护、虚拟内存或多任务处理等现代操作系统的功能。这种模式通常用于运行早期的操作系统(如MS-DOS)和一些嵌入式系统。虽然实模式的功能有限,但它是x86处理器的基础,为后来更复杂的保护模式(Protected Mode)打下了基础。
注意: Intel8086处理器没有IOPL(I/O特权级)和NT(嵌套任务)位
FLAGS是一个特殊的寄存器,其存储当前处理器的运行状态,其每一位的定义如下:
位 | 名称 | 描述 |
---|---|---|
0 | CF(进位标志) | 当执行加法、减法或位操作时,如果发生进位或借位,则该标志位置1,否则为0。 |
1 | 保留位 | 保留位,始终为1(不可使用)。 |
2 | PF(奇偶标志) | 表示结果中1的位数是偶数时置1,奇数时为0。 |
3 | 保留位 | 保留位,始终为0(不可使用)。 |
4 | AF(辅助进位标志) | 在二进制运算中,从低4位向高4位进位时置1,常用于BCD运算。 |
5 | 保留位 | 保留位,始终为0(不可使用)。 |
6 | ZF(零标志) | 当运算结果为0时置1,否则为0。 |
7 | SF(符号标志) | 表示运算结果的符号位,结果为负数时置1,正数时为0。 |
8 | TF(陷阱标志) | 用于单步调试。置1时,每执行一条指令后,处理器会产生一个单步中断。 |
9 | IF(中断使能标志) | 置1时使能外部硬件中断,置0时禁用中断。 |
10 | DF(方向标志) | 控制字符串操作的方向,置1时递减,置0时递增。 |
11 | OF(溢出标志) | 当有符号数运算的结果超过可表示的范围时置1,否则为0。 |
12-13 | IOPL(I/O特权级) | 仅在保护模式下使用,指定当前任务的I/O权限级别。 |
14 | NT(嵌套任务标志) | 用于控制多任务处理,仅在保护模式下使用。 |
15 | 保留位 | 保留位,始终为0(不可使用)。 |
实模式下中断可以分为硬中断和软中断,它们是处理器响应外部或内部事件的一种机制。
硬中断是由外部硬件设备(如键盘、时钟、I/O设备等)触发的中断信号。当这些设备需要处理器的即时响应时,它们通过中断控制器(如8259 PIC)发送中断信号给处理器。处理器在接收到硬中断信号后,会暂时中断当前正在执行的指令序列,保存现场(如寄存器状态)并跳转到对应的中断服务程序(ISR)来处理这个中断。
硬中断的特点是异步发生的,即不依赖于程序的执行流程,可能随时打断处理器的操作。每个硬中断都有一个特定的中断号,与中断向量表(IVT)中的中断向量相关联,处理器通过这个中断向量跳转到相应的中断处理程序。
软中断是由软件程序主动发出的中断指令(如INT指令)触发的。软中断通常用于系统调用或其他需要处理器立即响应的特殊操作。程序员可以通过指定中断号来调用相应的中断服务程序,以执行特定的功能,例如访问BIOS服务、进行磁盘操作或其他底层系统功能。
软中断的特点是同步发生的,即它们由程序代码中的指令触发,按照程序的执行流程发生。软中断在实模式下常用于与BIOS通信,以执行一些底层操作,如屏幕显示、磁盘读写等。
中断向量表是实模式下用于管理中断服务程序地址的一个内存数据结构。它位于内存的最低1 KB(通常是0x0000到0x03FF)处,共占用256个条目,每个条目为4个字节(32位),用于存储中断服务程序的段地址和偏移地址。
每个中断请求都有一个对应的中断号(0到255),处理器通过这个中断号在中断向量表中查找相应的中断服务程序(ISR)的入口地址。当一个中断发生时,处理器通过中断号访问中断向量表,获取对应的ISR地址,然后跳转到这个地址来执行中断处理。
中断向量表中的条目排列如下:
前2个字节:偏移地址,指定中断服务程序在段内的偏移。
后2个字节:段地址,指定中断服务程序所在的内存段。
在实模式下,中断向量表不仅用于硬件中断,还用于软件中断调用(如BIOS服务)。它是处理器响应中断请求的关键机制之一,确保系统能够正确地处理各种中断事件。
CPU在收到中断信号或者执行INT指令时会先保存现场,以便于中断返回后继续工作,中断发生的步骤如下:
处理器首先会自动将当前执行的指令的指令指针(IP)和代码段寄存器(CS)的值压入堆栈。这些值指向被中断的程序中的下一条指令地址。当中断处理完成后,处理器会从堆栈中弹出这些值,从而恢复被中断程序的执行。
紧接着,处理器会将标志寄存器(FLAGS)的内容压入堆栈。标志寄存器中的各个位标志当前的处理器状态,如进位标志(CF)、零标志(ZF)、溢出标志(OF)等。保存这些标志位是为了确保中断返回后处理器能恢复到正确的状态。
在保存现场之后,处理器通常会自动清除中断使能标志(IF),以禁止进一步的中断。这确保了当前中断服务程序可以不被其他中断打断地执行。某些中断服务程序可能需要手动恢复中断(通过设置IF标志),以允许更高优先级的中断在处理中被处理。
处理器通过中断向量表获取对应中断号的中断服务程序的地址,并跳转到该地址开始执行ISR。ISR通常是一个固定的例程,用于处理特定的中断事件。
中断服务程序执行完毕后,处理器需要将之前保存的现场恢复,以便继续执行被中断的程序。这个恢复过程通常包括:
从堆栈中弹出FLAGS寄存器,恢复中断前的状态。
从堆栈中弹出CS和IP寄存器,恢复到被中断的程序位置。
最后,处理器使用 IRET(Interrupt Return)
指令,从堆栈中弹出CS、IP和FLAGS寄存器,并恢复中断前的状态和指令流,从而继续执行被中断的程序。
通过这种机制,CPU能够在处理完中断事件后,无缝地恢复并继续执行中断前的任务,确保系统的稳定性和程序的正确性。