为什么主引导记录的内存地址是0x7C00?

作者: 阮一峰

日期: 2015年9月28日

《计算机原理》课本说,启动时,主引导记录会存入内存地址0x7C00。

这个奇怪的地址,是怎么来的,课本就不解释了。我一直有疑问,为什么不存入内存的头部、尾部、或者其他位置,而偏偏存入这个比 32KB 小1024字节的地方?

昨天,我读到一篇文章,终于解开了这个谜。

首先,如果你不知道,主引导记录(Master boot record,缩写为MBR)是什么,可以先读《计算机是如何启动的?》

简单说,计算机启动是这样一个过程。

  1. 通电
  2. 读取ROM里面的BIOS,用来检查硬件
  3. 硬件检查通过
  4. BIOS根据指定的顺序,检查引导设备的第一个扇区(即主引导记录),加载在内存地址 0x7C00
  5. 主引导记录把操作权交给操作系统

所以,主引导记录就是引导"操作系统"进入内存的一段小程序,大小不超过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)
+--------------------- (...)

(完)

留言(28条)

哈哈 考古文~

这真的很基础

阮老师很有探知原理机制的热情,这是极客精神啊

一个有意思的细节,涨姿势了

「为了把尽量多的连续内存留给操作系统,主引导记录就被放到了内存地址的尾部。」

这一点如果再加一句补充说明也许会更好理解:

「操作系统启动后,主引导记录就没有用处了,此后它所在的内存地址可以被操作系统重新利用」

上述有一处算错了,0x7FFF-512-512=0x7BFF 而非 0x7C00。0x7FFF-512-512+1=0x7C00

@Biao:

谢谢指出,已经改正了。

有意思,我当时看到了这个0x7C00,倒是也有这个疑问。不过还真没有想过去探寻一下,阮老师还真是有探寻精神,向阮老师学习。

引用Tevin的发言:

「为了把尽量多的连续内存留给操作系统,主引导记录就被放到了内存地址的尾部。」

这一点如果再加一句补充说明也许会更好理解:

「操作系统启动后,主引导记录就没有用处了,此后它所在的内存地址可以被操作系统重新利用」

这个倒是有可能哦,操作系统说不定还会把这段内存利用上呢。如果这样说的话,话在尾部不是没有用,而是为了操作系统可以重新利用上这段内存,我想这才是它放在尾部更重要的原因。

引用Tevin的发言:

「为了把尽量多的连续内存留给操作系统,主引导记录就被放到了内存地址的尾部。」

这一点如果再加一句补充说明也许会更好理解:

「操作系统启动后,主引导记录就没有用处了,此后它所在的内存地址可以被操作系统重新利用」

这个补充的好,不然我就觉得为了连续的内存说不通,主引导放在前面,后面也是可以连续的。

阮一峰老师应该也是参考下面这篇文章的吧。

[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.

弱弱的问一句,为什么搜索IT知识,阮大师的文章都在百度第一页。怎么做到的

引用司马牛的发言:

阮老师很有探知原理机制的热情,这是极客精神啊

引用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.


博主文笔很好,如果把引文列出来,更专业。
看了下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. ”

阮一峰老师的每一篇都是经典!难怪在搜索引擎排名这么好

这里有个邀请8人送书邀请28人送树莓派2的活动……要不要弄一个折腾下……(还是穷学生,借地宣传一下感谢)

https://account.daocloud.io/signup?invite_code=qscyw8lmeyhddm674ca3

0x7FFF - 512 - 512 + 1 = 0x7C00
为啥不是0x7BFF

您好,最近我在跟一个mit的操作系统课(mit6.828),在课程实验lab1里面提到:intel 8088 可以识别1MB空间,BIOS ROM是固定在0xf0000 -> 0xfffff(即960KB到1MB)的地址空间的,如您所述,早期PC基本只能配置16KB,32KB RAM。所以,您文章尾部画的图中 BIOS占用的地址空间位置是不是画错了呢(占用了RAM空间)?

阮老师谢谢你的探索,以前我也好奇过! 现在觉得自己学知识好痛苦,总是被各种背后知识困扰,就是想知道背后原理或更深一层的机制,但能力达不到而感到很痛苦。 网上看了这个有点像是 一种 性格特征叫:Low Latent Inhibition,( http://www.lowlatentinhibition.org/what-is-lli/ ),就是越狱主角在剧里被心理医生定性的特征,中文叫低潜在抑制症,不知阮老师是否有了解过这个?

当初网上找了半天也没找到0x7c00的出处,今天终于算是找到了。

0x7FFF - 512 - 512 + 1 = 0x7C00 ,其中的第一个512代表MBR本身(第一个扇区的大小),第二个代表MBR所产生的数据大小,最后那个+1代表什么意思,没有明白。

引用小霹雳的发言:

0x7FFF - 512 - 512 + 1 = 0x7C00 ,其中的第一个512代表MBR本身(第一个扇区的大小),第二个代表MBR所产生的数据大小,最后那个+1代表什么意思,没有明白。

这是计算的写法不明确。。0x7C00 - 0x7FFF 是两端都闭合的空间,所以根据右端点和长度来计算左端点的时候要加1。比如:[2,3,4,5],右端是5,长度是4,那么起点就是 5 - 4 + 1 = 2

搜索7C00搜到这儿了

这个字体不好,0和o和O居然分不清楚

感谢!想知道您平时是在哪里获取这些知识的?

(=°Д°=) 原来有那么多人发现了这个0x7c00的疑惑。

0x0000~0x03FF 放的是 Interrupts vectors,即中断向量表,不是中断处理程序

(主引导记录本身就是中断信号INT 19h的处理程序。)
这里描述似乎不对
INT 19h 负责加载主引导记录,所以 INT 19h 的处理程序应该是在 BIOS 里。

我要发表看法

«-必填

«-必填,不公开

«-我信任你,不会填写广告链接