cpu架构-x86

8086架构


8个16位通用寄存器(CPU 内部的数据单元)
其中的4个AX、BX、CX、DX 为可以分成两个 8 位的寄存器来使用,分别是 AH、AL、BH、BL、CH、CL、DH、DL。

其中 H 就是 High(高位),L 就是 Low(低位)的意思。

 

IP 寄存器
指令指针寄存器(Instruction Pointer Register),指向代码段中下一条指令的位置。

CPU 会根据它来不断地将指令从内存的代码段中,加载到 CPU 的指令队列中,然后交给运算单元去执行。

 

段寄存器
CS -代码段寄存器(Code Segment Register)
通过它可以找到代码在内存中的位置

 

DS -数据段寄存器(Data Segment Register)
通过它可以找到数据在内存中的位置。

 

SS -栈寄存器(Stack Register)
栈是程序运行中一个特殊的数据结构,数据的存取只能从一端进行,秉承后进先出的原则,push 就是入栈,pop 就是出栈。

 

段数据-寻址过程
对于一个段,有一个起始的地址,而段内的具体位置,我们称为偏移量(Offset)。

例如 8 号会议室的第三排,8 号会议室就是起始地址,第三排就是偏移量。

 

背景

在 CS 和 DS 中都存放着一个段的起始地址(16位)

代码段的偏移量在 IP 寄存器中,数据段的偏移量会放在通用寄存器中。

 

偏移量也是 16 位的,但 8086 的地址总线地址是 20 位

 

解决方案

起始地址 *16+ 偏移量

通过这个操作相当于将起始地址左移了4位,再加上偏移量,就能得到一个20位的数据地址了

 

局限

对于只有 20 位地址总线的 8086 来讲,能够区分出的地址也就 2^20=1M,超过这个空间就访问不到了。

如果想访问 1M+X 的地方,这个位置已经超过 20 位了,由于地址总线只有 20 位,在总线上超过 20 位的部分根本是发不出去的,所以发出去的还是 X,最后还是会访问 1M 内的 X 的位置。

在 32 位处理器中,有 32 根地址总线,可以访问 2^32=4G 的内存。

 

进化架构(32bit)


通用寄存器
扩展为8个32位的,但为了兼容性,仍然保持了8位和16位的使用方式

指向下一条指令的指令指针寄存器 IP,就会扩展成 32 位的,同样也兼容 16 位的。

 

段寄存器

扩展性的局限
因为原来的模式其实有点不伦不类,因为它没有把 16 位当成一个段的起始地址,也没有按 8 位或者 16 位扩展的形式,而是根据当时的硬件,弄了一个不上不下的 20 位的地址。

这样每次都要左移四位,也就意味着段的起始地址不能是任何一个地方,只是能整除 16 的地方。

 

新的定义
CS、SS、DS、ES 仍然是 16 位的,但是不再是段的起始地址。段的起始地址放在内存的某个地方。

这个地方是一个表格,表格中的一项一项是段描述符(Segment Descriptor)。这里面才是真正的段的起始地址。而段寄存器里面保存的是在这个表格中的哪一项,称为选择子(Selector)。

这样,将一个从段寄存器直接拿到的段起始地址,就变成了先间接地从段寄存器找到表格中的一项,再从表格中的一项中拿到段起始地址。这样段起始地址就会很灵活了。

当然为了快速拿到段起始地址,段寄存器会从内存中拿到 CPU 的描述符高速缓存器中。

 

兼容性
32 位的系统架构下,前一种模式称为实模式(Real Pattern),后一种模式称为保护模式(Protected Pattern)。

当系统刚刚启动的时候,CPU 是处于实模式的,这个时候和原来的模式是兼容的。

当需要更多内存的时候,进行一系列的操作,切换到保护模式,就能够用到 32 位 CPU 的特性。

所以事实上是不能无缝兼容的,需要通过切换模式兼容。

 

 

上一篇:Visual Studio 2017 软件打包 - 安装与部署


下一篇:substr,repace,regexp_repalce,regexp_instr 函数的用法