《计算机原理》课本说,启动时,主引导记录会存入内存地址0x7C00。
这个奇怪的地址,是怎么来的,课本就不解释了。我一直有疑问,为什么不存入内存的头部、尾部、或者其他位置,而偏偏存入这个比 32KB 小1024字节的地方?
昨天,我读到一篇文章,终于解开了这个谜。
首先,如果你不知道,主引导记录(Master boot record,缩写为MBR)是什么,可以先读《计算机是如何启动的?》。
简单说,计算机启动是这样一个过程。
- 通电
- 读取ROM里面的BIOS,用来检查硬件
- 硬件检查通过
- BIOS根据指定的顺序,检查引导设备的第一个扇区(即主引导记录),加载在内存地址 0x7C00
- 主引导记录把操作权交给操作系统
所以,主引导记录就是引导"操作系统"进入内存的一段小程序,大小不超过1个扇区(512字节)。
0x7C00这个地址来自Intel的第一代个人电脑芯片8088,以后的CPU为了保持兼容,一直使用这个地址。
1981年8月,IBM公司最早的个人电脑IBM PC 5150上市,就用了这个芯片。
当时,搭配的操作系统是86-DOS。这个操作系统需要的内存最少是32KB。我们知道,内存地址从0x0000开始编号,32KB的内存就是0x0000~0x7FFF
。
8088芯片本身需要占用0x0000~0x03FF
,用来保存各种中断处理程序的储存位置。(主引导记录本身就是中断信号INT 19h的处理程序。)所以,内存只剩下0x0400~0x7FFF
可以使用。
为了把尽量多的连续内存留给操作系统,主引导记录就被放到了内存地址的尾部。由于一个扇区是512字节,主引导记录本身也会产生数据,需要另外留出512字节保存。所以,它的预留位置就变成了:
0x7FFF - 512 - 512 + 1 = 0x7C00
0x7C00就是这样来的。
计算机启动后,32KB内存的使用情况如下。
+--------------------- 0x0 | Interrupts vectors +--------------------- 0x400 | BIOS data area +--------------------- 0x5?? | OS load area +--------------------- 0x7C00 | Boot sector +--------------------- 0x7E00 | Boot data/stack +--------------------- 0x7FFF | (not used) +--------------------- (...)
(完)
Muninn 说:
哈哈 考古文~
2015年9月28日 11:30 | # | 引用
L 说:
这真的很基础
2015年9月28日 15:17 | # | 引用
司马牛 说:
阮老师很有探知原理机制的热情,这是极客精神啊
2015年9月28日 17:35 | # | 引用
Learner 说:
一个有意思的细节,涨姿势了
2015年9月28日 20:56 | # | 引用
Tevin 说:
「为了把尽量多的连续内存留给操作系统,主引导记录就被放到了内存地址的尾部。」
这一点如果再加一句补充说明也许会更好理解:
「操作系统启动后,主引导记录就没有用处了,此后它所在的内存地址可以被操作系统重新利用」
2015年9月28日 21:59 | # | 引用
Biao 说:
上述有一处算错了,0x7FFF-512-512=0x7BFF 而非 0x7C00。0x7FFF-512-512+1=0x7C00
2015年9月30日 00:55 | # | 引用
阮一峰 说:
@Biao:
谢谢指出,已经改正了。
2015年9月30日 07:15 | # | 引用
欧文 说:
有意思,我当时看到了这个0x7C00,倒是也有这个疑问。不过还真没有想过去探寻一下,阮老师还真是有探寻精神,向阮老师学习。
2015年10月 5日 05:26 | # | 引用
欧文 说:
这个倒是有可能哦,操作系统说不定还会把这段内存利用上呢。如果这样说的话,话在尾部不是没有用,而是为了操作系统可以重新利用上这段内存,我想这才是它放在尾部更重要的原因。
2015年10月 5日 06:13 | # | 引用
SG 说:
这个补充的好,不然我就觉得为了连续的内存说不通,主引导放在前面,后面也是可以连续的。
2015年10月 7日 09:47 | # | 引用
TD 说:
阮一峰老师应该也是参考下面这篇文章的吧。
[Why BIOS loads MBR into 0x7C00 in x86 ?](http://www.glamenv-septzen.net/en/view/6) 原文如是说。
BIOS developer team decided 0x7C00 because:
1. They wanted to leave as much room as possible for the OS to load itself within the 32KiB.
2. 8086/8088 used 0x0 - 0x3FF for interrupts vector, and BIOS data area was after it.
3. The boot sector was 512 bytes, and stack/data area for boot program needed more 512 bytes.
So, 0x7C00, the last 1024B of 32KiB was chosen.
2015年10月 7日 15:59 | # | 引用
帅小武 说:
弱弱的问一句,为什么搜索IT知识,阮大师的文章都在百度第一页。怎么做到的
2015年10月16日 10:21 | # | 引用
阮文武 说:
2015年10月18日 19:37 | # | 引用
XYL 说:
博主文笔很好,如果把引文列出来,更专业。
看了下TD给出的链接,文章里写的更清楚:“Once OS loaded and started, boot sector is never used until power reset. So, OS and application can use the last 1024B of 32KiB freely. ”
2015年10月26日 10:04 | # | 引用
whywhywhy 说:
阮一峰老师的每一篇都是经典!难怪在搜索引擎排名这么好
这里有个邀请8人送书邀请28人送树莓派2的活动……要不要弄一个折腾下……(还是穷学生,借地宣传一下感谢)
https://account.daocloud.io/signup?invite_code=qscyw8lmeyhddm674ca3
2015年10月28日 22:41 | # | 引用
jaychang 说:
0x7FFF - 512 - 512 + 1 = 0x7C00
为啥不是0x7BFF
2016年5月26日 09:00 | # | 引用
Joseph 说:
您好,最近我在跟一个mit的操作系统课(mit6.828),在课程实验lab1里面提到:intel 8088 可以识别1MB空间,BIOS ROM是固定在0xf0000 -> 0xfffff(即960KB到1MB)的地址空间的,如您所述,早期PC基本只能配置16KB,32KB RAM。所以,您文章尾部画的图中 BIOS占用的地址空间位置是不是画错了呢(占用了RAM空间)?
2016年7月15日 16:44 | # | 引用
雨下路人 说:
阮老师谢谢你的探索,以前我也好奇过! 现在觉得自己学知识好痛苦,总是被各种背后知识困扰,就是想知道背后原理或更深一层的机制,但能力达不到而感到很痛苦。 网上看了这个有点像是 一种 性格特征叫:Low Latent Inhibition,( http://www.lowlatentinhibition.org/what-is-lli/ ),就是越狱主角在剧里被心理医生定性的特征,中文叫低潜在抑制症,不知阮老师是否有了解过这个?
2016年7月29日 15:17 | # | 引用
幻奇拓 说:
当初网上找了半天也没找到0x7c00的出处,今天终于算是找到了。
2016年8月 9日 17:07 | # | 引用
小霹雳 说:
0x7FFF - 512 - 512 + 1 = 0x7C00 ,其中的第一个512代表MBR本身(第一个扇区的大小),第二个代表MBR所产生的数据大小,最后那个+1代表什么意思,没有明白。
2016年12月 1日 12:16 | # | 引用
xesam 说:
这是计算的写法不明确。。0x7C00 - 0x7FFF 是两端都闭合的空间,所以根据右端点和长度来计算左端点的时候要加1。比如:[2,3,4,5],右端是5,长度是4,那么起点就是 5 - 4 + 1 = 2
2016年12月28日 11:19 | # | 引用
mjzhou 说:
搜索7C00搜到这儿了
2017年3月 5日 21:42 | # | 引用
izhaoi 说:
这个字体不好,0和o和O居然分不清楚
2018年1月17日 10:24 | # | 引用
周娜 说:
感谢!想知道您平时是在哪里获取这些知识的?
2018年5月30日 19:17 | # | 引用
美丽是真的 说:
(=°Д°=) 原来有那么多人发现了这个0x7c00的疑惑。
2022年8月22日 21:43 | # | 引用
龍蝦 说:
0x0000~0x03FF 放的是 Interrupts vectors,即中断向量表,不是中断处理程序
2023年8月10日 21:01 | # | 引用
龍蝦 说:
(主引导记录本身就是中断信号INT 19h的处理程序。)
这里描述似乎不对
INT 19h 负责加载主引导记录,所以 INT 19h 的处理程序应该是在 BIOS 里。
2023年8月11日 10:05 | # | 引用