8086的储存器编址
8086的储存器编址
值得注意的是JOS是採用8086进行操作系统搭建的!
本来认为一无是处的8086,如今认为真要好好学学了,由于JOS,哈哈
在操作系统底层经常会遇到"逻辑地址"的概念,各种地址混淆在一起,极易头疼...
http://blog.csdn.net/cinmyheart/article/details/39843857
上面的Link是我对虚拟地址,线性地址,物理地址进行的分析.
----------------------------------------------------------------------------------------------------------------------------------
首先引出一个问题,非常多人都知道,段寻址的方式是
segment:offset,比方0x0:0x7c2d
这是8086在实模式下的物理寻址方式.
问题: 你有没有想过,为什么是这样寻址? 根本的原因在哪儿?
这篇blog就试图回答这个问题.
8086有20根地址线,2^(20) == 1MB的储存器地址空间.这1MB的储存单元依照0x00000~0xFFFFF来编址.
8086有16根数据线,2^(16) == 64KB.
矛盾就凸显出来了,试问,能用寄存器直接对全部的地址空间进行寻址嘛?
明显不能, 数据线的宽度小于地址线的宽度!
所以,为了对全部1MB的储存器地址空间进行寻址,有人想出了,"一块块寻址"的办法 ---- 分段寻址机制.
想想,整个内存能够达到16个段(2^4).
在为程序分配内存空间的时候,一个程序能够有代码段CS,数据段DS,堆栈段SS和附加段ES
于是就有了段寻址, seg:offset. == (seg << 4) + offset.
这里seg和offset都能够用16位的寄存器存储,进而构造出了20bit的物理地址.
如果我们要对代码段内的某个指令进行寻址,我们能够
CS:IP
假设我们要对数据段内某个数据进行寻址,我们能够
DS:register 这里register能够是IP,甚至能够是BX
假设我们要对堆栈段进行寻址,我们能够
SS:SP 或SS:BP
等等.
接着还有个问题,为什么我们电脑关机之后再又一次冷启动,按下启动电源键.
电脑每次都正确无误的启动,是不是按下电源键之后,电脑都进行了"某些同样的动作"?
当然, 每次按下电源键, CPU都会复位, 一切从新開始.
而对于8086来说,复位后,全部寄存器的值都是0,除了CS == 0xFFFF,即代码段(这都是硬件project师有益设计好的)
接着,这是实模式,于是进行段寻址,
CS:IP == 0xFFFF0
寻址结果显示,复位之后,第一条CPU应该运行的指令在物理地址0xFFFF0处.
于是计算机就開始启动啦~ 每次都从0xFFFF0開始.
能够发现,开机后第一条指令,当前地址是0xFFFF0. 在此之前,CS == 0x0000
细心点会发现,第一条语句在段0xF000内, 此时,CS == 0xF000
CS = 0xFFFF IP = 0x0000的时候 CPU在自己初始化,
CPU初始化完毕之后。系统立即进入实模式,CS变成 0xF000 IP=0xFFF0
我们利用JOS进行验证
The IBM PC starts executing at physical address 0x000ffff0, which is at the very top of the 64KB area reserved for the ROM BIOS.
The PC starts executing with CS = 0xf000 and IP = 0xfff0.
The first instruction to be executed is a jmp instruction, which jumps to the segmented address CS = 0xf000 and IP = 0xe05b .
update: 2014.12.21
补充一下,有意思的是依据CSAPP得知,core i7 的地址线长度和数据线长度各自是48bits,52bits
强调一下,以上讨论寻址,都是讨论的实模式下的寻址.
如有错漏,恳请指正交流 : )
update :2015.04.19
修正了之前关于系统启动时CS段的笔误
摄于南苑