第一条指令的地址

  在用户按下计算机电源开关之后,CPU会自动的将其CS寄存器设定为0xFFFF,将其IP寄存器设定为0x0000。由于CS:IP指出了下一条指令的地址[1],因此CPU会跳到0xFFFF:0x0000处进行执行。为什么是这个地址而不是其它地址呢?这其实是一个很巧妙的设计。

  我们知道,从80386开始,到后面80486、奔腾,它们都是32位的CPU,但是它们都与Intel先前开发的8086兼容。也就是说,在默认情况下,80386、80486等,只不过是一台运行得更快一些的8086罢了。因此,这里我们只讨论8086[2]

  8086是16位的CPU,但是却有20根地址线[3]。也就是说它可以寻址 220 = 1M 内存空间。这段内存空间由RAM、ROM组成。ROM是随机只读存储器,里面的程序是在计算机出厂的时候直接烧录在里面的,完成一些主机自检等操作,并提 供一些访问磁盘等基本输入输出服务,因而这段程序常被称为BIOS(Basic Input/Ouput Service)。由于不同的计算机厂商生产的计算机所带的外设不一样,因此,这段程序大小也限机型的不同而不一样,有可能A厂出产的计算机所带的这段程 序的大小为1K,而B厂出产的这段程序的大小为2K。如果将这段程序放在0x0000处,那么用户写的程序就可能从0x0400处开始也可能从 0x0800处开始,非常不统一。故而,将此段程序放在1M内存的顶部,那么用户写的程序就都可以从0x0000处开始了。

  但将BIOS这段程序放在1M内存的顶部,如果这段程序大小为1K,那么应当从0xFFC00开始放。如果这段程序的大小为2K,那 么应当从0xFF800开始放,对于CPU而言,到底是应当从0xFFC00开始执行还是应当从0xFF800开始执行呢?为了解决这个问题,8086规 定,CPU均从0xFFFF0处开始执行,而在0xFFFF0处,放一条无条件转移指令JMP。如果A厂的BIOS是从0xFFC00开始放的,那么这条 转移指令就跳转到0xFFC00处开始执行。如果B厂的BIOS是从0xFF800开始放的,那么这条转移指令就跳转到0xFF800处开始执行,各个厂 家可以跟据自己所生产的BIOS程序的大小,来决定此转移指令具体跳转到的位置。

  这里有一点需要清楚的是,通常认为,内存编址是连续的,不会出现空洞,其实完全不是这样。比如,假设BIOS的编址是从 0xF0000开始,而RAM,即通常讲的内存编址是从0x00000开始,那么,如果用户只安装了32K内存,那么内存的编址范围就是 0x00000~0x07FFF,那么从0x08000至0xEFFFF处就没有安装内存,这就是一个内存空洞。

  好了,当CPU执行了放在0xFFFF0处的第一条指令后,就跳转到BIOS程序内部去执行了,下面就来看看BIOS都做了些什么。

BIOS的工作

  BIOS的工作相当简单,主要的工作就是执行主机自检(POST),然后查找操作系统存在在哪个磁盘上,将操作系统载入。BIOS在查找各磁盘 的操作系统时,主要是查找磁盘上的第一个扇区(0面0磁道1扇区),每个扇区是512字节,如果这是一个引导扇区,那么就将它载入0x7C00的内存地址上,然后跳转到此地址上执行。如果此不是一个引导扇区,就继续查找下一个磁盘,看其上面是否存在引导扇区。如果所有的磁盘上都不存在引导扇区,则在屏幕上 打印出一条出错信息。

 

引导扇区的工作

  引导扇区只有一扇区即512字节大,因此它的主要目的是把操作系统的内核读进内存,然后跳转到操作系统内核处开始执行。从编写操作系统角度来 说,前面的CPU上电及BIOS的工作都不是操作系统能控制的,而从引导扇区开始,就完完全全可由操作系统来控制了,因此,编写引导扇区也是编写操作系统 必要的工作之一。从BIOS跳入引导扇区后,计算机系统引导工作就算完成,怎样把操作系统内核读进内存,然后再安排一条跳转指令跳到内核处执行就是操作系 统开发人员的工作了。

intelx86为何从0xFFFF0处执行的更多相关文章

  1. C语言实现程序跳转到绝对地址0x100000处执行

    嵌入式笔试题:想让程序跳转到绝对地址0x100000处执行,该如何做? 请详细解释一下所给的答案: 网上看到有如下答案: *((void(*)(void))0x100000)(); 经过在VC++6. ...

  2. 【Node.js】Event Loop执行顺序详解

    本文基于node 0.10.22版本 关于EventLoop是什么,请看阮老师写的什么是EventLoop 本文讲述的是EventLoop中的执行顺序(着重讲setImmediate, setTime ...

  3. Java Main如何被执行?(转)

    java应用程序的启动在/hotspot/src/share/tools/launcher/java.c的main()函数中,而在虚拟机初始化过程中,将创建并启动Java的Main线程.最后将调用JN ...

  4. erlang虚拟机代码执行原理

     转载:http://blog.csdn.NET/mycwq/article/details/45653897 erlang是开源的,很多人都研究过源代码.但是,从erlang代码到c代码,这是个不小 ...

  5. mysql 批处理命令执行多个sql脚本

    方法1 若有SQL脚本a.sql, b.sql, 其目录在f盘根目录下, 则可再写一个SQL脚本c.sql(假设其目录也在f盘根目录下, 也可以在其他路径下)如下: source f:/a.sql; ...

  6. Java Main如何被执行?

    java应用程序的启动在在/hotspot/src/share/tools/launcher/java.c的main()函数中,而在虚拟机初始化过程中,将创建并启动Java的Main线程.最后将调用J ...

  7. [WEB安全]无回显代码执行【转载】

    原作者:AdminTony 原文链接:http://www.admintony.com/无回显代码执行利用方法.html 在Root-Me上有一道代码执行的题目,其链接为题目链接 0x01 简介 打开 ...

  8. python函数的执行过程

    对于 Python 常规函数,都只有一个入口,但会有多个出口如 return 返回或者抛出异常.函数从入口进入会一直运行到 return 语句或者抛出异常,中间不会暂停,函数一直拥有控制权.当运行结束 ...

  9. linux 驱动学习笔记03--Linux 内核的引导

    如图所示为 X86 PC 上从上电/复位到运行 Linux 用户空间初始进程的流程.在进入与 Linux相关代码之间,会经历如下阶段. ( 1 ) 当系统上电或复位时, CPU 会将 PC 指针赋值为 ...

随机推荐

  1. python面试题-django相关

    1.中间件 中间件一般做认证或批量请求处理,django中的中间件,其实是一个类,在请求和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法, 如请求过来 执行process_re ...

  2. trade可撤销贪心正确性证明

    鉴于tarde这道题正解过于好写,导致我对这个诡异的贪心的正确性产生了疑问,所以花了2h的时间与同机房神犇M-Blanca,Midoria7,goote~进行讨论,最后与goote~犇犇各得出了一个正 ...

  3. 互不侵犯(洛谷P1896)

    题目:在N*N的棋盘里面放k个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入输出:输入N,K,输出有几种放置方法. ...

  4. .net core 3.1 vs2019报HTTP Error 500.30 - ANCM In-Process Start Failure

    vs启动报此错误的话查看自己的程序是3.1.1还是3.1.2.解决防范安装高版本的重启

  5. Afinal简介和使用方法

    Afinal简介 Afinal 是一个android的sqlite orm 和 ioc 框架.同时封装了android中的http框架,使其更加简单易用: 使用finalBitmap,无需考虑bitm ...

  6. 使用PL/SQL Developer 学习pl/sql

    1.创建表并且插入一些数据 (这里表名为test): 2. New 一个SQL Window敲下如下代码(--为注释部分): declare   --declare:用于plsql中的声明变量,和be ...

  7. airtest操作夜神模拟器adb冲突解决办法

    首先看错误日志明显是adb之间版本不对应互相干掉对方 第一步 去aritestIde所在目录\AirtestIDE\airtest\core\android\static\adb\windows 第二 ...

  8. Stream(三)

    public class Test08 { /* * 二.中间的加工操作 * (1)filter(Predicate p):过滤 * (2)distinct():去重 * (3)limit(long  ...

  9. hive drop和恢复partition external table

    在hdfs目录:/user/xx/table/test_external 保存 test_external 表数据 先建表,使用列式存储格式 CREATE external TABLE `test_e ...

  10. webpack 单独打包指定JS文件

    背景 最近接到一个需求,因为不确定打出的前端包所访问的后端IP,需要对项目中IP配置文件单独拿出来,方便运维部署的时候对IP做修改.因此,需要用webpack单独打包指定文件. CommonsChun ...