计算机启动

六、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。

相关推荐
xcLeigh11 小时前
HTML5超酷响应式视频背景动画特效(六种风格,附源码)
前端·音视频·html5
ZhaiMou1 天前
HTML5拖拽API学习 托拽排序和可托拽课程表
前端·javascript·学习·html5
懒羊羊我小弟3 天前
CSS回顾-CSS选择器详解
前端·css·html·css3·html5
逸曦穆泽3 天前
html5 实现视频播放
前端·音视频·html5
xcLeigh3 天前
HTML5实现剪刀石头布小游戏(附源码)
前端·html·html5
Java Fans3 天前
从零开始打造个人博客:我的网页设计之旅
css·html5
贩卖纯净水.4 天前
HTML5和CSS3新增特性
前端·css3·html5
不爱说话郭德纲4 天前
理解 Object.create 并正确使用 Object.create
前端·javascript·vue.js·es6·html5
伏飞而行5 天前
七、利用CSS和多媒体美化页面的习题
前端·css·html5
Akiiiira5 天前
【网页设计】HTML5 和 CSS3 提高
前端·css3·html5