计算机启动

六、0x7c00 是啥

把某设备上(比如硬盘)的程序复制到内存中的过程 。那加载启动区这个过程,翻译过来就是,BIOS 程序把启动区的内容复制到了内存中的某个区域。

什么是启动区呢?即使你不知道,你也应该能够猜到,一定是符合某种特征的一块区域,于是人们把它就叫做启动区了,那要符合什么特征呢?先不急,不知道你有没有过设置 BIOS 启动顺序的经历,通常有 U 盘启动、硬盘启动、软盘启动、光盘启动等等,BIOS 会按照顺序,读取这些启动盘中位于 0 盘 0 道 1 扇区的内容

至于磁盘格式的划分,就不做讲解了,总之对于内存,我们给出一个数字地址就能获取到该地址的数据,而对于磁盘,我们需要给出磁头、柱面、扇区这三个信息才能定位某个位置的数据,都是描述位置的一种方式而已。

接着说, 这 0 盘 0 道 1 扇区的内容一共有 512 个字节,如果末尾的两个字节分别是 0x55 和 0xaa,那么 BIOS 就会认为它是个启动区。如果不是,那么按顺序继续向下个设备中寻找位于 0 盘 0 道 1 扇区的内容。如果最后发现都没找到符合条件的,那直接报出一个无启动区的错误。

BIOS 找到了这个启动区之后干嘛呢?哦,前面说过了是加载,就是把这 512 个字节的内容,一个比特都不少的全部复制到内存的 0x7c00 这个位置。怎么复制的?当然是指令。哪些指令呢?这里我只能简单说指令集中是有 in 和 out 的,用来将外设中的数据复制到内存,或者将内存中的数据复制到外设,用这两个指令,以及外设给我们提供的读取方式,就能做到这一点啦。

启动区内容此时已经被 BIOS 程序复制到了内存的 0x7c00 这个位置,然后呢?这个其实也不难猜测,启动区的内容就是我们自己写的代码了,复制到这里之后,就开始执行呗,之后我们的程序就接管了接下来的流程,BIOS 的使命也就结束啦。所以复制完之后,接下来应该是一个跳转指令吧!没错,正是这样,PC 寄存器的值变为 0x7c00,指令开始从这里执行。

开头我们说:

BIOS 把控制权转交给排在第一位的存储设备。

所以这句话是什么意思呢?就是 BIOS 把启动区的 512 字节复制到内存的 0x7c00 位置,并且用一条跳转指令将 pc 寄存器的值指向 0x7c00

为什么非要是 0x7c00 呢?好问题,当然答案也很简单,那就是人家 BIOS 开发团队就是这样定的,之后也不好改了,不然不兼容。为什么不好改?我们看一个简单的启动区 512 字节的代码。

复制代码
; hello-os
; TAB=4

  ORG  0x7c00   ;程序加载到内存的 0x7c00 这个位置

;程序主体

entry:
  MOV  AX,0   ;初始化寄存器
  MOV  SS,AX
  MOV  SP,0x7c00
  MOV  DS,AX   ;段寄存器初始化为 0
  MOV  ES,AX
  MOV  SI,msg
putloop:
  MOV  AL,[SI]
  ADD  SI,1
  CMP  AL,0   ;如果遇到 0 结尾的,就跳出循环不再打印新字符
  JE  fin
  MOV  AH,0x0e   ;指定文字
  MOV  BX,15   ;指定颜色
  INT  0x10   ;调用 BIOS 显示字符函数
  JMP  putloop
fin:
  HLT
  JMP  fin
msg:
  DB  0x0a,0x0a  ;换行、换行
  DB  "hello-os"
  DB  0x0a   ;换行
  DB  0    ;0 结尾

  RESB 0x7dfe-$   ;填充0到512字节
  DB 0x55, 0xaa   ;可启动设备标识

我们看第一行:

复制代码
ORG  0x7c00

这个数字就是刚刚说的启动区加载位置,这行汇编代码简单说就表示把下面的地址统统加上 0x7c00。正因为 BIOS 将启动区的代码加载到了这里,因此有了一个偏移量,所以所有写启动区代码的人就需要在开头写死一个这样的代码,不然全都串位了。

然后正因为所有写操作系统的,启动区的第一行汇编代码都写死了这个数字,那 BIOS 开发者最初定的这个数字就不好改了,否则它得挨个联系各个操作系统的开发厂商,说我这个地址改一下,你们跟着改改。在公司推动另一个团队改个代码都得大费周折。

再看最后一行:

复制代码
DB 0x55, 0xaa

这也验证了我们之前说的这 512 字节的最后两个字节得是 0x55 0xaa,BIOS 才会认为它是一个启动区,才会去加载它,仅此而已。

回过头来说 0x7c00 这个值,它其实就是一个规定死的值,但还是会有人问,那必然有它的合理性吧。其实,我的解释也只能说是人家规定了这个值,后人们替他们解释这个合理性,并不是说当初人家就一定是这样想的,就好比我们做语文的阅读理解题一样。

第一个 BIOS 开发团队是 IBM PC 5150 BIOS,当时被认为的第一个操作系统是 DOS 1.0 操作系统,BIOS 团队就假设是为它服务的。但操作系统还没出,BIOS 团队假设其操作系统需要的最小内存为 32 KB。BIOS 希望自己所加载的启动区代码尽量靠后,这样比较"安全",不至于过早的被其他程序覆盖掉。可是如果仅仅留 512 字节又感觉太悬了,还有一些栈空间需要预留,那扩大到 1 KB 吧。这样 32 KB 的末尾是 0x8000,减去 1KB(0x400) ,刚好等于 0x7c00。

相关推荐
Amy.Wang3 小时前
前端如何实现电子签名
前端·javascript·html5
veminhe8 小时前
html怎么设置html5
html·html5
失落的多巴胺21 小时前
使用deepseek制作“喝什么奶茶”随机抽签小网页
javascript·css·css3·html5
veminhe11 天前
HTML5 浏览器支持
前端·html·html5
伍哥的传说11 天前
react gsap动画库使用详解之text文本动画
前端·vue.js·react.js·前端框架·vue·html5·动画
veminhe12 天前
HTML5简介
前端·html·html5
蹦极的考拉16 天前
在使用 HTML5 的 <video> 标签嵌入视频时,有时会遇到无法播放 MP4 文件的问题
前端·音视频·html5
木木黄木木16 天前
HTML5 火焰字体效果教程
前端·html·html5
于本淡16 天前
一篇文章快速学会HTML
开发语言·前端·数据结构·qt·html·json·html5
TE-茶叶蛋17 天前
HTML5 更新的功能
前端·html·html5