DOS引导扇区代码详解
msdos源码解读
MS-DOS(Microsoft Disk Operating System)是微软公司开发的操作系统,最早于1981年发布。
由于MS-DOS的源代码并非公开可用,因此我们无法直接提供完整的MS-DOS源码解读。
然而,我可以向您介绍一些关于MS-DOS的基本原理和结构。
MS-DOS是一个基于命令行界面的操作系统,主要设计用于IBM PC和兼容机。
它的源代码在编写时主要使用汇编语言(如8086汇编语言),以及部分C语言。
MS-DOS的源码包含了各种功能和模块,其中一些重要的部分包括:
1. 引导扇区(Boot Sector):这是引导操作系统的第一个扇区,通常位于存储介质的起始位置。
它包含了启动加载程序,用于加载操作系统的其他部分。
2. 文件系统:MS-DOS使用FAT(File Allocation Table)文件系统,它负责管理磁盘上文件的存储和组织。
FAT文件系统的源代码涉及到文件的创建、读取、写入、删除等操作。
3. 命令解释器(Command Interpreter):MS-DOS提供了一个命令行解释器,用户可以通过命令行输入来与系统交互。
命令解释器的源码包括命令解析、执行和输出等功能。
4. 设备驱动程序:MS-DOS的源代码还包括了与硬件设备交互的驱动程序,如磁盘驱动器、键盘驱动器等。
这些驱动程序负责向应用程序提供对设备的访问接口。
需要注意的是,由于MS-DOS的源码并非公开可用,因此一般人无法直接查看和解读其完整的源代码。
然而,通过学习操作系统原理、汇编语言和相关文档,可以深入理解MS-DOS的工作原理和内部结构。
1。
dos指令解析
dos指令解析DOS指令解析是指对DOS操作系统中常用的命令进行解读和理解,并提供相应的解释和示例。
DOS(Disk Operating System)是一种早期的个人计算机操作系统,它使用命令行界面来与计算机进行交互。
一、DIR指令DIR指令是DOS中最常用的命令之一,用于显示当前目录中的文件和子目录列表。
通过在命令行中输入"DIR",系统将显示当前目录中的文件名、大小、日期和时间等信息。
这个命令非常有用,可以帮助用户确认文件的存在、查找特定文件或目录,以及了解文件的属性。
例如,输入"DIR /S /P"命令可以显示当前目录及其所有子目录中的文件列表,以及按页显示,方便用户浏览文件。
二、CD指令CD指令用于更改当前目录。
通过在命令行中输入"CD 目录名",系统将切换到指定的目录。
这个命令非常有用,可以帮助用户快速切换目录,进入到工作目录或者其他相关目录。
例如,输入"CD C:\Windows"命令可以切换到Windows目录,用户可以在该目录下执行其他操作。
三、COPY指令COPY指令用于复制文件或目录。
通过在命令行中输入"COPY 源文件目标位置",系统将从源文件复制内容到目标位置。
这个命令非常有用,可以帮助用户在不同位置间快速复制文件或整个目录。
例如,输入"COPY C:\file.txt D:\Backup"命令将文件C:\file.txt复制到D:\Backup目录中,用户可以在备份目录中保存文件的副本。
四、DEL指令DEL指令用于删除文件。
通过在命令行中输入"DEL 文件名",系统将删除指定的文件。
这个命令非常有用,可以帮助用户清理无用的文件或者执行特定的文件管理任务。
例如,输入"DEL C:\Temp\temp.txt"命令将删除C:\Temp目录下的temp.txt文件。
DOS的启动过程详解
DOS的启动过程详解DOS(Disk Operating System)是一种由微软公司开发的操作系统,它是早期个人电脑领域最流行的操作系统之一、下面是DOS的启动过程的详细解释。
1. 加电自检(Power-On Self-Test,POST):当计算机加电时,硬件系统会进行一系列自检程序来确保系统硬件的正常工作。
这包括检查RAM、键盘、磁盘驱动器和其他设备。
2. 主引导记录(Master Boot Record,MBR):在启动过程的开始阶段,计算机会读取硬盘的主引导记录。
MBR是一个引导扇区,它位于硬盘的第一个扇区(LBA0),通常是512字节大小。
3. 引导加载程序(Boot Loader):MBR中的引导代码读取硬盘的分区表(Partition Table),找到活动分区(Active Partition),然后加载该分区的引导扇区(Boot Sector)到RAM中的低地址。
这个引导扇区通常被称为引导加载程序。
在DOS系统中,这个引导加载程序通常是IO.SYS。
4.DOS启动文件加载:引导加载程序在加载完毕后,将控制权转交给DOS的两个主要启动文件之一IO.SYS。
IO.SYS是DOS系统的核心文件,它负责对硬件设备进行初始化和提供对硬件访问的接口。
5.系统配置文件加载:IO.SYS加载后,会读取系统配置文件CONFIG.SYS。
CONFIG.SYS是一个文本文件,其中包含了一些重要的系统参数和设备驱动程序的加载指令。
这些指令用于配置计算机的硬件和软件环境。
7.用户登录或直接进入命令行环境:DOS系统启动后,通常会提示用户输入用户名和密码来登录系统。
如果用户没有设置密码,或者系统配置文件中没有配置要求登录,那么系统会直接进入命令行环境。
8.用户命令执行:一旦进入命令行环境,用户可以通过输入各种命令来操作计算机。
DOS提供了众多的命令和功能,例如文件管理、目录切换、文件复制等。
总结起来,DOS的启动过程可以分为硬件自检、MBR读取、引导加载程序加载、DOS启动文件加载、系统配置文件加载、命令行解释器加载、用户登录或直接进入命令行环境以及用户命令执行等多个步骤。
常见dos命令详细解释-也算是杀毒基础知识了
常见dos命令详细解释-也算是杀毒基础知识了一)MD——建立子目录1.功能:创建新的子目录2.类型:内部命令3.格式:MD[盘符:][路径名]〈子目录名〉4.使用说明:(1)“盘符”:指定要建立子目录的磁盘驱动器字母,若省略,则为当前驱动器;(2)“路径名”:要建立的子目录的上级目录名,若缺省则建在当前目录下。
例:(1)在C盘的根目录下创建名为FOX的子目录;(2)在FOX子目录下再创建USER 子目录。
C:\>MD FOX (在当前驱动器C盘下创建子目录FOX)C:\>MD FOX \USER (在FOX 子目录下再创建USER子目录)(二)CD——改变当前目录1.功能:显示当前目录2.类型:内部命令3.格式:CD[盘符:][路径名][子目录名]4.使用说明:(1)如果省略路径和子目录名则显示当前目录;(2)如采用“CD\”格式,则退回到根目录;(3)如采用“CD..”格式则退回到上一级目录。
例:(1)进入到USER子目录;(2)从USER子目录退回到子目录;(3)返回到根目录。
C:\>CD FOX \USER(进入FOX子目录下的USER子目录)C:\FOX\USER>CD.. (退回上一级根目录)C:\FOX>CD\ (返回到根目录)C:\>(三)RD——删除子目录命令1.功能:从指定的磁盘删除了目录。
2.类型:内部命令3.格式:RD[盘符:][路径名][子目录名]4.使用说明:(1)子目录在删除前必须是空的,也就是说需要先进入该子目录,使用DEL(删除文件的命令)将其子目录下的文件删空,然后再退回到上一级目录,用RD命令删除该了目录本身;(2)不能删除根目录和当前目录。
例:要求把C盘FOX子目录下的USER子目录删除,操作如下:第一步:先将USER子目录下的文件删空;C\>DEL C:\FOX\USER\*。
*第二步,删除USER子目录。
C\>RD C:\FOX\USER(四)DIR——显示磁盘目录命令1.功能:显示磁盘目录的内容。
DOS分区体系的主引导记录扇区-MBR
DOS分区体系的主引导记录扇区-MBR使用DOS分区体系时,磁盘的第一个扇区――也就是0号扇区被称为主引导记录扇区,也称为MBR(主引导记录,Master Boot Recorder--MBR)。
当计算机启动并完成自检后,首先会寻找磁盘的MBR扇区并读取其中的引导记录,然后将系统控制权交给它。
由此可见,如果MBR损坏,则后续的所有工作都无法继续进行。
1. MBR数据结构MBR由446个字节的引导代码、64个字节的主分区表及2个字节的签名值“55AA”组成。
我们首先使用Winhex来看一下MBR扇区的内容,如图2.11所示(因为该磁盘尚未进行分区操作,所以分区表全部为空)。
图2.11 主引导记录扇区可以看到,MBR扇区由三大部分组成:(1)引导代码。
MBR接管系统的控制权后,引导代码负责对其他代码信息进行检查(比如查看是否有“55AA”有效标记)并进一步引导系统。
(2)分区表。
分区表负责描述磁盘内的分区情况。
(3)“55AA”有效标志。
“55AA”标志做为有效标志以通知系统该MBR扇区是否有效,如果该标志丢失或损坏,磁盘将会显示为“未初始化”。
MBR扇区的数据结构如表2.1所示。
表2.1MBR扇区数据结构字节偏移(十六进制)字节数描述00~1BD446引导代码1BE~1CD16分区表项11CE~1DD16分区表项21DE~1ED16分区表项31EE~1FD16分区表项41FE~1FF2签名值(55AA)具体含义解释如下:1)0x00~0x1BD:446个字节,引导代码区域,包含一段指令,用以通知计算机如何访问分区表并定位操作系统的位置。
◆ 主引导代码是一段非常重要的代码,因为它是磁盘上最先装入内存并执行的代码。
也正因为如此,很多引导型病毒把自己嵌入到主引导代码中,从而实现首先运行的目的。
标准的Microsoft引导代码会在计算机启动完成自检并将控制权交给它后,读取分区表并根据分区表项的可引导标志判定哪个主分区是引导分区,找到这个分区后就查看并读取位于该分区第一个扇区的引导代码并进而启动操作系统,这部分代码会因操作系统的不同而不同。
dos命令详解dos命令大全
dos命令详解dos命令大全你还在为不知道dos命令详解而不知所措么?下面来是店铺为大家收集的dos命令详解,欢迎大家阅读:dos命令详解2.dir 盘符:路径文件名字:表示指定目录下是否有这个文件,若盘符:路径与当前盘符:路径相同,可以省略盘符:路径。
例如:dir c:windowssystem32calc.exe 就是表示查看system32目录下是否有该calc.exe文件,如果有就会提示没有则不提示,如果在C盘查找该文件时,加上/s则可以在C盘所有目录下搜索该文件。
3.dir *.exe 或 dir asp.* :支持通配符查看,前者表示查看所有exe 文件,后者表示查看名字为asp任意后缀文件。
文件多建议配合/p。
4./p 参数:表示在dir浏览的时候可以一屏一屏地显示,并且按任意键继续浏览。
5./w :横向显示文件和目录名称,一般分为三排,但不显示文件的创建时间、数量。
其中用中[]括起来的是目录。
6./a :如果直接是/a那么就显示所有属性的文件,包括dir看不到的系统隐藏属性的文件。
下面是/a的子参数,子参数可以多个,例如/ahs就是显示隐藏和系统属性的。
属性开关可以组合使用,但属性之间不能用空格隔开。
中间也可以使用冒号进行表示,例如dir /a:h带子参数:dir /ad 只显示目录dir /ah:只显示隐藏属性的文件(h=hidden 隐藏的)dir /ar 只显示只读属性的文件(r=read) dir /as:只显示系统文件(s=system) dir /aa:只显示存档属性文件(a=archive)dir /a-h 显示非隐藏性的文件 dir /a-s:显示非系统属性的文件dir /a-d 仅显示任意属性文件,不显示文件夹。
dir /a-a :显示没有更改过的存档文件dir /a-r 显示非只读属性的文件。
7./s :表示显示该目录以及该目录下所有子目录中的文件夹和文件。
例如dir /s c:就会显示C盘下所有文件包括windows、system32等C盘全部目录以及目录下子目录下的文件。
DOS命令学习(从入门到精通)
DOS命令学习(从入门到精通)DOS命令学习一、DOS使用常识DOS(Disk Operating System)是一个使用得十分广泛的磁盘操作系统。
常见的DOS有两种:IBM公司的PC-DOS和微软公司的MS-DOS,它们的功能、命令用途格式都同样,我们经常使用的是MS-DOS。
DOS的概况DOS(Disk Operating System)是一个使用得十分广泛的磁盘操作系统,就连目前流行的Windows9x/ME系统都是以它为基础。
常见的DOS有两种:IBM公司的PC-DOS和微软公司的MS-DOS。
它们的功能、命令用途格式都同样,我们经常使用的是MS-DOS。
二、DOS的内部命令DOS的内部命令是进行操作的基础,完毕了对它们的学习就跨进了DOS系统的大门。
内部命令,是指在DOS启动之后,自己主动通过文件导入内存的命令。
在执行这些命令的时候,直接从内存进行调用………1) dir--显示指定路径上全部文件或文件夹的信息它的格式为'dir [盘符:][路径][文件名称] [參数]',比方'DIR E:\FF.M3U'。
2) md(mkdir)--建立文件夹它的格式为'md [盘符][路径]'。
比如'MD TEMP'。
3) rd(rmdir)--删除文件夹格式为'RD [盘符][路径]'。
注意:该命令仅仅能删除空文件夹。
而且不能删除当前文件夹。
4) cd--进入指定文件夹格式为' CD [路径]'。
比如'CD HAPPY'。
注意:仅仅能进入当前盘符中的文件夹。
当中'CD\'为回到根文件夹,'CD..'为回到上一层文件夹。
5) copy--复制文件格式为'COPY [源文件夹或文件] [目的文件夹或文件]',比方'COPY C:\*.COM D:\'注意:使用该命令进行文件拷贝时,目的文件夹一定要存在。
硬盘主引导扇区和系统引导扇区的维...
实训9 硬盘主引导扇区和系统引导扇区的维护一、实训辅导:(一)DEBUG程序在维护(读取、修改和备份)硬盘OSBR系统引导扇区(即DOS引导扇区或物理0柱面1磁头1扇区,也就是0-1-1扇区)时的应用1、用L命令将0-1-1扇区内容读入至内存CS:0100的方法:-L CS:0100 2 0 1回车,以后可用D命令查看:-D CS:0100 L n 回车(n为16进制字节数,CS:0100为要读的起始地址)2、用E或F命令改写已读入内存中的0-1-1扇区内容的方法(以将最后三字节00 55 AA改写为11 44 BB为例):-D 02FD L3 回车,显示 00 55 AA-E 02FD 11 44 BB 回车,用E命令修改三个字节-D 02FD L3 回车显示11 44 BB 说明三个字节已修改成功-F 02FD L3 00 55 AA 回车,用F命令改回原来数据00 55 AA-D 02FD L3 回车,显示 00 55 AA,说明改回成功-F 02FD 02FF 11 44 BB 回车,再用F命令的另一种用法修改-D 02FD L3 回车,显示 11 44 BB,说明已修改成功3、将内存中的从CS:0100---02FF这512B写入硬盘0-1-1扇区的方法:-W CS:0100 2 0 1回车,写入以后可再用L 命令读入内存:-L CS:0100 2 0 1回车,读至内存以后,再用D命令查看:-D 0100 L200 回车,显示从0100---02FF的200H字节,最后三字节为11 44BB,用E或F命令将其再改回为 00 55 AA :-E 02FD 00 55 AA 回车或者–F 02FD 02FF 00 55 AA 回车或者-F 02FD L3 00 55 AA回车,再用D命令查看:-D 02FD L3 回车显示00 55 AA-W 0100 2 0 1回车(写盘)-L 0100 2 0 1回车(读盘)-D 0100 L200 回车(查看512字节)4、将0-1-1扇区存为备份文件BOOTSECT.BAK的方法DEBUG回车-N A:\BOOTSECT.BAK回车(定义保存路径和文件名)-L 0100 2 0 1回车(将扇区读至内存)-RCX回车CX 0000:200回车(计划要写的字节数为200H,即512字节)-W回车(将内存写200H字节到文件)WRITING 00200 BYTES-Q回车此时可在A:\下看到已生成大小为512字节的文件BOOTSECT.BAK5、将0-1-1扇区的备份文件BOOTSECT.BAK重写回0-1-1扇区的方法DEBUG回车- N A:\BOOTSECT.BAK回车- L CS:0500回车(读文件内容到内存)- D 0500 L200回车(查看,此句可省)- D 06FD L3回车(只查看最后三个字节 00 55 AA ,此句可省)- W 0500 2 0 1回车- Q回车(二)DEBUG程序在维护硬盘MBR主引导扇区(即物理0柱面0磁头1扇区,也就是0-0-1扇区)时的应用1 、这0-0-1扇区,为主引导扇区,不属于任何分区和任何操作系统,因而不能用简单的DOS命令读出和写入(硬盘上其它扇区都可以用简单的DOS命令读出和写入,唯有0-0-1扇区不能简单地用DOS命令读写)。
DOS下分区图解(巨详细,零基础也可分区)
第一步我们首先要引导光盘进入光盘启动界面,然后选择DOS工具箱,因为我们是要使用DOS功能来对硬盘进行分区,此方法主要是是用在使用各种方法都无效的时候,因为其他的图形界面分区工具都比较简单易用。
选择之后很快就可以进入到DOS界面了,现在表示在等待输入状态:
接下来输入DOS下分区命令:FDISK
输入命令之后就会启动相应的程序:询问是否启用大硬盘的支持,即是否在分区上使用FAT32文件系统,默认使用
选择Y之后进入如下界面:出现了功能选择项
我们选择1,也就是输入1然后回车,出现如下图:
图中已经说明各个选择项的功能了,我们选择第一项创建主DOS分区
询问是否要把所有可用的硬盘空间都创建为1个主DOS分区,为了腾出硬盘空间来创建逻辑分区,在这里我们选择N然后再回车。
提示输入主DOS分区的大小
这里我们选择创建一个2000M的主DOS分区,输入之后回车。
分区成功之后我们还要把分出来的主分区设置为活动才可以在开机时引导系统
主分区创建完了,我们还需要把剩下的硬盘分区也分下来,接下来我们创建扩展分区,当然创建成主分区也可以,不过主分区只可以最多创建4个,而逻辑分区对数量是没有限制的,所以我们分区为逻辑分区,当然如果要安装多操作系统就要再分一两个主分区了。
通过选择上面图的第二项选择项,进入逻辑分区界面,跟创建主分区是一样的操作,输入要分区的容量大小,然后回车
如图接下图输入第一个逻辑分区的大小:
回车:
此时第一个逻辑分区创建成功了,按ESC即可回到主菜单:
提示必须重新启电脑才能使分区生效,并且所有分区必须格式化后才能使用
全部格式化之后重启就可以安装操作系统了,安装方法:。
硬盘主引导扇区MBRDPTDBRBPB详解
为了使加载文件的操作更加灵活,加上 FAT32 文件系统采用"活动"
的 FDT 表,,同时考虑到引导程序的代码量和为今后发展保留适当的余量,FAT32 文
件系统分区引导扇区占据了 6 个扇区,只有前 3 个扇区作为系统的分区引导扇区,其
余 3 个扇区保留暂未使用。分区引导扇区对于操作系统的启动和磁盘文件的访问具有至 关重要的作用;引导程序代码的损坏将导致操作系统不能正常启动,磁盘读写参数的破 坏将造成存储在磁盘上的文件不能正常读写。
硬盘分区表分为四小部分,每一小部分表示一个分区的信息,占 16 字节。在这里我们 可以看出,硬盘的总分区数为什么不能大于 4。其中可激活分区数不得大于 3,扩展分 区数不得大于 1,当前活动分区数必须小于等于 1。
分区表的每一分区的第 0 个字节是自举标志,其值为 80H 时,表示该分区是当前 活动分区,可引导,其值为 00H 时,表示该分区不可引导。
扩展分区中的每个逻辑驱动器都存在一个类似于 MBR 的扩展引导记录(Extended Boot Record,EBR)(图四)。
扩展引导记录包括一个扩展分区表和扇区结束标志 55AA。一个逻辑驱动器中的引 导扇区一般位于相对扇区 32 或 63。
如果磁盘上没有扩展分区,那么就不会有扩展引导记录和逻辑 驱动器。第一个逻辑驱动器的扩展分区表中的第一项指向它自身的引导扇区;第二项指 向下一个逻辑驱动器的 EBR,如果不存在进一步的逻辑驱动器,第二项就不会使用,而 被记录成一系列零。如果有附加的逻辑驱动器,那么第二个逻辑驱动器的扩展分区表的 第一项会指向它本身的引导扇区,第二个逻辑驱动器的扩展分区表的第二项指向下一个 逻辑驱动器的 EBR。扩展分区表的第三项和第四项永远都不会被使用。
引导扇区代码分析
引导扇区代码分析:07C0:0000FA cli;禁止中断07C0:000133C0xor ax,ax07C0:00038ED0mov ss,ax;初始化运行堆栈,将SS:SP指向运行代码前07C0:0005BC007C mov sp,7C0007C0:0008FB sti;允许中断07C0:00098CC8mov ax,cs07C0:000B8ED8mov ds,ax;将DS指向CS相同地址,此处操作比较浪费,只用了一次07C0:000D52push dx;引导扇区运行时DX保存当前引导磁盘号;下面几条指令用于取得装入偏移地址,由于不能直接对IP进行mov指令;所以使用一条CALL指令利用堆栈将IP取出07C0:000E E80000call0011;执行一条函数调用指令,从而将下一条指令的地址压入堆栈07C0:00115E pop si;取出刚刚压入的地址07C0:001281EE1100sub si,0011;减掉偏转地址得到实际的开始偏移07C0:00167412je002A;如果偏移为零跳转;判断装入地址是否为0000:7C00如果是则使用远跳转进行地址转换到003707C0:001881FE007C cmp si,7C00;装入偏移是否为7C0007C0:001C7575jne009307C0:001E8CC8mov ax,cs;取得装入段地址,此句多余,见000907C0:00203D0000cmp ax,0000;装入段地址是否为000007C0:0023757F jne00A407C0:0025EA3700C007jmp0037;使用远跳转指令进行地址转换;判断装入地址是否为0000如果是则直接进行运行到003707C0:002A C606AE0133mov byte ptr[01AE],33;修改错误代码为"3",意义为装载地址错误07C0:002F90nop07C0:00308CC8mov ax,cs;多余,同001E07C0:00323DC007cmp ax,07C0;装入段地址是否为07C007C0:0035757E jne00B5;前面这段代码用于解决不同系统装入地址的问题,合法地址为0000:7C00或07C0:0000;如果地址不正确,则进行错误处理,运行到此处地址应全部转换为07C0:003707C0:00378CC8mov ax,cs;取什么取,一定是07C0了07C0:00398ED8mov ds,ax;这次才真的有用,见000B07C0:003B C606AE0134mov byte ptr[01AE],34;修改错误代码为"4",意义为非法引导盘07C0:004090nop07C0:004180FA80cmp dl,80;查看当前引导磁盘号是否小于80,即不是硬盘或CDROM07C0:0044726F jb00B5;如果是则转移错误处理07C0:0046C606AE0135mov byte ptr[01AE],35;修改错误代码为"5",意义为引导扇区非法或不完整07C0:004B90nop07C0:004C BBFE07mov bx,07FE;BX指向引导扇区结尾标志07C0:004F8B07mov ax,[bx];取出标志07C0:00513D55AA cmp ax,AA55;是否为AA5507C0:0054755F jne00B5;如果不是,则转移错误处理;装载BOOTFIX.BIN并运行,显示"Press any key to boot from CD";如果没有此文件则直接跳过07C0:00565A pop dx;恢复引导磁盘号07C0:005788169904mov[0499],dl;保存磁盘号至数据区07C0:005B688A04push048A;"BOOTFIX.BIN"文件名的地址07C0:005E6A0B push000B;文件名长度为1107C0:0060680020push2000;装载起始段地址200007C0:0063E87603call03DC;调用装载函数07C0:00660F820F00jb0079;如果不成功则直接跳过07C0:006A60pusha07C0:006B1E push ds07C0:006C06push es;保存当前运行现场07C0:006D8A169904mov dl,[0499];取出当前引导磁盘号07C0:00719A00000020call2000:0000;运行刚刚装载的BOOTFIX.BIN 07C0:007607pop es07C0:00771F pop ds07C0:007861popa;恢复运行现场;装载SETUPLDR.BIN并运行07C0:0079687E04push047E;"SETUPLDR.BIN"文件名的地址07C0:007C6A0C push000C;文件名长度为1207C0:007E680020push2000;装载起始段地址200007C0:0081E85803call03DC;调用装载函数07C0:00840F823500jb00BD;如果不成功则转错误处理07C0:00888A169904mov dl,[0499];取出当前引导磁盘号07C0:008C33C0xor ax,ax07C0:008E680020push200007C0:009150push ax;在堆栈中制造2000:0000的返回地址07C0:0092CB retf;转移到2000:0000运行刚装载的SETUPLDR.BIN;由07C0:001C转此07C0:009356push si07C0:00948BDE mov bx,si07C0:009681C3AE01add bx,01AE;计算偏移07C0:009A C60731mov byte ptr[bx],31;修改错误代码为"1",意义为引导段地址错误07C0:009D81C68A01add si,018A;"CDBOOT:Cannot boot from CD-Code:"07C0:00A1EB2A jmp00CD;显示并重新引导07C0:00A390nop;由07C0:0023转此07C0:00A456push si07C0:00A58BDE mov bx,si07C0:00A781C3AE01add bx,01AE07C0:00AB C60732mov byte ptr[bx],32;修改错误代码为"2",意义为引导偏移地址错误07C0:00AE81C68A01add si,018A;"CDBOOT:Cannot boot from CD-Code:"07C0:00B2EB19jmp00CD;显示并重新引导07C0:00B490nop;由07C0:0035,07C0:0044,07C0:0054转此07C0:00B56A00push000007C0:00B7BE8A01mov si,018A;"CDBOOT:Cannot boot from CD-Code:"07C0:00BA EB11jmp00CD;显示并重新引导07C0:00BC90nop;由07C0:0084转此07C0:00BD6A00push000007C0:00BF BEB201mov si,01B2;"CDBOOT:Couldn't find NTLDR"07C0:00C2EB09jmp00CD;显示并重新引导07C0:00C490nop;由07C0:0367转此07C0:00C56A00push000007C0:00C7BED001mov si,01D0;"CDBOOT:Memory overflow error"07C0:00CA EB01jmp00CD;显示并重新引导07C0:00CC90nop;显示并重新引导,si中为要显示的信息07C0:00CD E80400call00D4;显示si中的信息07C0:00D05E pop si;恢复引导扇区被装载的偏移地址07C0:00D1EB12jmp00E5;开始错误处理07C0:00D390nop;显示信息函数,入口:;si:信息起始地址,0结尾07C0:00D4AC lodsb;取一个字符07C0:00D50AC0or al,al;是否结尾07C0:00D70F840900je00E407C0:00DB B40E mov ah,0E07C0:00DD BB0700mov bx,000707C0:00E0CD10int10;显示07C0:00E2EBF0jmp00D407C0:00E4C3ret;错误处理,此间地址可能因装载地址不同有所不同,所以使用si作为基础地址进行地址运算;首先延时0024次时钟中断,即36*55=1980ms,大约两秒07C0:00E5C7846B042400mov word ptr[si+046B],0024;设定延时计数器为002407C0:00EB FA cli07C0:00EC06push es07C0:00ED33C0xor ax,ax07C0:00EF8EC0mov es,ax;es指向中断地址表07C0:00F1BB2000mov bx,0020;bx指向中断08的偏移07C0:00F4268B07mov ax,es:[bx]07C0:00F789846704mov[si+0467],ax07C0:00FB268B4702mov ax,es:[bx+02]07C0:00FF89846904mov[si+0469],ax;保存原中断08的地址到0467 07C0:010*******mov es:[bx],si07C0:010********D01add word ptr es:[bx],016D07C0:010B268C4F02mov es:[bx+02],cs;将中断08指向07C0:016B07C0:010F07pop es07C0:0110FB sti07C0:011183BC6B0400cmp word ptr[si+046B],0000;查看计数器是否结束07C0:011675F9jne011107C0:0118FA cli07C0:011906push es07C0:011A33C0xor ax,ax07C0:011C8EC0mov es,ax07C0:011E BB2000mov bx,002007C0:01218B846704mov ax,[si+0467]07C0:0125268907mov es:[bx],ax07C0:01288B846904mov ax,[si+0469]07C0:012C26894702mov es:[bx+02],ax;恢复刚才保存的中断08的地址07C0:013007pop es07C0:0131FB sti;将引导扇区代码移动到2000:0000,以便在07C0:0000装载新的引导扇区07C0:01321E push ds07C0:013306push es07C0:0134B80020mov ax,200007C0:01378EC0mov es,ax07C0:01398CC8mov ax,cs07C0:013B8ED8mov ds,ax07C0:013D33FF xor di,di07C0:013F B90008mov cx,080007C0:0142F3repz07C0:0143A4movsb07C0:014407pop es07C0:01451F pop ds07C0:0146EA4B010020jmp2000:014B;转移到;在07C0:0000装载硬盘的引导扇区此段代码执行时已经被移动到2000:014B07C0:014B06push es07C0:014C B8C007mov ax,07C007C0:014F8EC0mov es,ax07C0:0151BB0000mov bx,000007C0:0154B80102mov ax,020107C0:0157B90100mov cx,000107C0:015A BA8000mov dx,008007C0:015D CD13int1307C0:015F0F830200jnb016507C0:0163EBFE jmp0163;如果装载失败,则死循环07C0:016507pop es07C0:0166B280mov dl,8007C0:0168EA007C0000jmp0000:7C00;转移到硬盘引导扇区处理;新的中断08处理程序,每次中断产生都将计数器减一,减至零为止07C0:016D9C pushf07C0:016E FA cli07C0:016F2E83BC6B0400cmp word ptr cs:[si+046B],0000;计数器是否为零07C0:01750F840500je017E07C0:01792EFF8C6B04dec word ptr cs:[si+046B];不为零则减一07C0:017E9D popf07C0:017F2EFFB46904push word ptr cs:[si+0469]07C0:01842EFFB46704push word ptr cs:[si+0467];将原中断地址压入堆栈07C0:0189CB retf;转入系统中断处理程序继续处理;错误提示信息07C0:018A DB"CDBOOT:Cannot boot from CD-Code:"07C0:01AE DB"0",0D,0A,00;错误代码07C0:01B2DB"CDBOOT:Couldn't find NTLDR",0D,0A,0007C0:01D0DB"CDBOOT:Memory overflow error",0D,0A,00;以下为前面的代码中使用的函数;从刚刚读取的目录中搜索指定的字符串;这段的作用就是在整个目录中查找指定的文件;查找的时候考虑了远指针的最小化偏移;并且考虑了跨段的查找问题;纯粹算法,没什么逻辑,所以比较烦琐,也比较无聊;如果想了解的话可以自己查iso9660里面有关目录项的内容去一行行详细分析07C0:01F0C606B10400mov byte ptr[04B1],00;07C0:01F590nop07C0:01F68B0E9E04mov cx,[049E];取出读取的字符数低位07C0:01FA FC cld07C0:01FB33DB xor bx,bx;es:bx指向目录开始07C0:01FD33D2xor dx,dx07C0:01FF8B36AD04mov si,[04AD];要搜索的字符串的地址07C0:0203268A17mov dl,es:[bx];取该目录项长度07C0:020680FA00cmp dl,00;如果长度为零,则跳过该项07C0:02090F843B00je024807C0:020D8BC3mov ax,bx07C0:020F052100add ax,0021;加21H指向目录项中文件名07C0:02128BF8mov di,ax07C0:021451push cx07C0:021533C9xor cx,cx07C0:02178A0EAF04mov cl,[04AF];cx为字符串长度07C0:021B F3repz07C0:021C A6cmpsb;比较字符串07C0:021D59pop cx07C0:021E0F846F00je0291;如果相同07C0:02223BD1cmp dx,cx;比较目录项长度与总长度的低位07C0:02240F833700jnb025F;如果不足则处理总长度高位07C0:02282BCA sub cx,dx;从总长度低位中减掉当前目录项长度07C0:022A803EB10401cmp byte ptr[04B1],0107C0:022F0F841A00je024D07C0:023303D3add dx,bx;偏移地址加本目录项指向下一目录项07C0:02358BDA mov bx,dx07C0:023783E30F and bx,000F07C0:023A51push cx07C0:023B B104mov cl,0407C0:023D D3EA shr dx,cl07C0:023F59pop cx07C0:02408CC0mov ax,es07C0:024203C2add ax,dx07C0:02448EC0mov es,ax;最小化远指针偏移07C0:0246EBB7jmp01FF07C0:0248BA0100mov dx,0001;设定长度为一,直接进入下次比较07C0:024B EBD5jmp022207C0:024D41inc cx07C0:024E C606B10400mov byte ptr[04B1],0007C0:025390nop07C0:0254EBDD jmp023307C0:0256C606B10401mov byte ptr[04B1],0107C0:025B90nop07C0:025C EB29jmp028707C0:025E90nop07C0:025F833EA00400cmp word ptr[04A0],0000;总长度高位是否为零07C0:02640F850200jne026A;如果不为零则继续处理07C0:0268F9stc;没有找到07C0:0269C3ret07C0:026A832EA00401sub word ptr[04A0],0001;高位减一07C0:026F03DA add bx,dx;偏移地址加本目录项指向下一目录项07C0:027153push bx07C0:027251push cx07C0:0273B104mov cl,0407C0:0275D3EB shr bx,cl07C0:027759pop cx07C0:02788CC0mov ax,es07C0:027A03C3add ax,bx07C0:027C8EC0mov es,ax;最小化远指针偏移07C0:027E5B pop bx07C0:027F83E30F and bx,000F07C0:02822BD1sub dx,cx07C0:028474D0je025607C0:02864A dec dx07C0:0287B8FFFF mov ax,FFFF07C0:028A2BC2sub ax,dx07C0:028C8BC8mov cx,ax;得到新的总长度的地位剩余值07C0:028E E96EFF jmp01FF;继续查找07C0:0291803EB00401cmp byte ptr[04B0],01;此次查找是否是子目录07C0:02960F840A00je02A4;如果是子目录则转子目录属性检查07C0:029A26F6471902test byte ptr es:[bx+19],02;查看目录属性是否为文件07C0:029F7581jne0222;如果不是继续查找07C0:02A1EB0A jmp02AD07C0:02A390nop07C0:02A426F6471902test byte ptr es:[bx+19],02;查看目录属性是否为子目录07C0:02A90F8475FF je0222;如果不是则继续查找07C0:02AD A0AF04mov al,[04AF]07C0:02B026384720cmp es:[bx+20],al;比较文件名长度07C0:02B40F856AFF jne0222;不相同则继续比较07C0:02B8F8clc;清除标记,查找成功07C0:02B9C3ret;下面的几个函数使用了类C的参数传递方法;所以大家看到了熟悉的push bp/mov bp,sp指令对;但是显然作者对高级语言函数堆栈组织不很熟悉,;连函数结尾的mov sp,bp也生搬了过来;这条指令是高级语言用来释放自动局部变量的;而这里的几个函数则根本没有使用局部变量;其实如果使用局部变量的话这里的几个函数会比较好看一些,;我指的是看起来比较象C的反汇编代码;呵呵;读指定扇区到内存,使用扩展磁盘读写;考虑到DOS下的64K数据段的限制,读操作是循环执行的.07C0:02BA55push bp07C0:02BB8BEC mov bp,sp07C0:02BD53push bx07C0:02BE56push si07C0:02BF52push dx07C0:02C050push ax;保存寄存器07C0:02C1BB6D04mov bx,046D;bx指向扩展磁盘读结构07C0:02C4C60710mov byte ptr[bx],1007C0:02C7C6470100mov byte ptr[bx+01],0007C0:02CB C6470300mov byte ptr[bx+03],0007C0:02CF C747040000mov word ptr[bx+04],000007C0:02D4C7470C0000mov word ptr[bx+0C],000007C0:02D9C7470E0000mov word ptr[bx+0E],0000;全部清除;将调用参数复制到临时数据区07C0:02DE8B460C mov ax,[bp+0C]07C0:02E1A3A204mov[04A2],ax07C0:02E48B460A mov ax,[bp+0A]07C0:02E7A3A404mov[04A4],ax;读盘总扇区数,32位,分两次处理07C0:02EA8B4608mov ax,[bp+08]07C0:02ED A3A604mov[04A6],ax;数据区的段地址07C0:02F08B4606mov ax,[bp+06]07C0:02F3A3A804mov[04A8],ax07C0:02F68B4604mov ax,[bp+04]07C0:02F9A3AA04mov[04AA],ax;开始逻辑扇区号,32位;以上将调用时传递的参数保存在数据区以便使用,;其实大可不必,既然用了类C的参数传递,;那么完全可以直接使用这些实参当变量用07C0:02FC813EA4040000cmp word ptr[04A4],000007C0:03020F851900jne031F07C0:0306813EA2042000cmp word ptr[04A2],002007C0:030C0F8F0F00jg031F;总扇区数是否小于20;保证每次读取的数据量不超过64K.;如果总扇区数小于20H,即20H*800H=10000H,正好是64K一个数据段的尺寸;注意,这里处理的是CDROM的扇区,所以扇区大小是800H,2048字节07C0:0310C6067D0400mov byte ptr[047D],00;清除标记标示不需段处理07C0:031590nop07C0:0316A1A204mov ax,word ptr[04A2]07C0:0319A2AC04mov byte ptr[04AC],al;直接读取总扇区数07C0:031C EB0D jmp032B07C0:031E90nop07C0:031F C6067D0401mov byte ptr[047D],01;置标记标示需要段处理07C0:032490nop07C0:0325C606AC0420mov byte ptr[04AC],20;每次固定读取20个扇区,即64K 数据07C0:032A90nop07C0:032B A0AC04mov al,[04AC]07C0:032E884702mov[bx+02],al;扇区数07C0:0331A1A604mov ax,[04A6]07C0:0334894706mov[bx+06],ax;数据区的段地址07C0:0337A1A804mov ax,[04A8]07C0:033A894708mov[bx+08],ax07C0:033D A1AA04mov ax,[04AA]07C0:034089470A mov[bx+0A],ax;开始逻辑扇区号07C0:0343BE6D04mov si,046D07C0:0346B442mov ah,4207C0:03488A169904mov dl,[0499];取出引导磁盘号07C0:034C CD13int13;操作07C0:034E803E7D0401cmp byte ptr[047D],01;是否还需要读取?07C0:03530F852200jne037907C0:0357832EA20420sub word ptr[04A2],002007C0:035C831EA40400sbb word ptr[04A4],0000;总扇区数减掉2007C0:03618106A6040010add word ptr[04A6],1000;数据段地址减掉1000,指向下一个64K.07C0:03670F825AFD jb00C5;如果溢出则转错误07C0:036B8106A8042000add word ptr[04A8],002007C0:03718116AA040000adc word ptr[04AA],0000;开始逻辑扇区号加2007C0:0377EB83jmp02FC;开始下一次循环读取07C0:037958pop ax;恢复寄存器07C0:037A5A pop dx07C0:037B5E pop si07C0:037C5B pop bx07C0:037D8BE5mov sp,bp07C0:037F5D pop bp07C0:0380C3ret;从指定扇区开始读取指定的字节数到内存;调用02BA完成读取07C0:038155push bp07C0:03828BEC mov bp,sp07C0:038451push cx07C0:038553push bx07C0:038650push ax;将字节数转换为逻辑扇区数,不足一个扇区按照一个扇区计算07C0:0387B10B mov cl,0B07C0:03898B1EA004mov bx,[04A0]07C0:038D A19E04mov ax,[049E]07C0:03900FADD8shrd ax,bx,cl07C0:0393D3EB shr bx,cl;将bx:ax右移11位,即除2048 07C0:0395F7069E04FF07test word ptr[049E],07FF;低位是否为零07C0:039B7406je03A307C0:039D050100add ax,000107C0:03A083D300adc bx,0000;不是则加一07C0:03A350push ax07C0:03A453push bx;总扇区数07C0:03A5FF7604push word ptr[bp+04];段地址07C0:03A8FF369A04push word ptr[049A]07C0:03AC FF369C04push word ptr[049C];开始逻辑扇区号07C0:03B0E807FF call02BA;读扇区07C0:03B383C40A add sp,000A07C0:03B658pop ax;恢复寄存器07C0:03B75B pop bx07C0:03B859pop cx07C0:03B98BE5mov sp,bp07C0:03BB5D pop bp07C0:03BC C3ret;取出目录项的起始扇区和字节数07C0:03BD50push ax07C0:03BE268B4702mov ax,es:[bx+02]07C0:03C2A39A04mov[049A],ax07C0:03C5268B4704mov ax,es:[bx+04]07C0:03C9A39C04mov[049C],ax;开始逻辑扇区号07C0:03CC268B470A mov ax,es:[bx+0A]07C0:03D0A39E04mov[049E],ax07C0:03D3268B470C mov ax,es:[bx+0C]07C0:03D7A3A004mov[04A0],ax;字节数07C0:03DA58pop ax07C0:03DB C3ret;装载函数,入口为:文件名地址,文件名长度,装载段地址07C0:03DC55push bp07C0:03DD8BEC mov bp,sp;读CDROM引导信息07C0:03DF6A01push000107C0:03E16A00push0000;总扇区数0000000107C0:03E3680010push1000;段地址100007C0:03E66A10push001007C0:03E86A00push0000;开始逻辑扇区号0000001007C0:03EA E8CDFE call02BA;读扇区07C0:03ED83C40A add sp,000A;取出root目录信息07C0:03F0B80010mov ax,100007C0:03F38EC0mov es,ax07C0:03F526A19E00mov ax,es:[009E]07C0:03F9A39A04mov[049A],ax07C0:03FC26A1A000mov ax,es:[00A0]07C0:0400A39C04mov[049C],ax;开始逻辑扇区号07C0:040326A1A600mov ax,es:[00A6]07C0:0407A39E04mov[049E],ax07C0:040A26A1A800mov ax,es:[00A8]07C0:040E A3A004mov[04A0],ax;读取字节数07C0:0411680010push1000;段地址100007C0:0414E86AFF call0381;读数据07C0:041783C402add sp,0002;在root目录中中搜索"I386"07C0:041A C706AD049504mov word ptr[04AD],0495;"I386"地址07C0:0420C606AF0404mov byte ptr[04AF],04;长度407C0:042590nop07C0:0426C606B00401mov byte ptr[04B0],01;置目录项标记,查找时检查是否为子目录07C0:042B90nop07C0:042C E8C1FD call01F0;开始搜索07C0:042F7234jb0465;如果没有找到;将找到的"I386"目录读出来07C0:0431E889FF call03BD;取出起始扇区和字节数07C0:0434680010push100007C0:0437E847FF call0381;读取扇区07C0:043A83C402add sp,0002;在I386中搜索调用函数时的指定文件07C0:043D B80010mov ax,100007C0:04408EC0mov es,ax07C0:04428B4608mov ax,[bp+08]07C0:0445A3AD04mov[04AD],ax;文件名地址07C0:04488A4606mov al,[bp+06]07C0:044B A2AF04mov byte ptr[04AF],al;文件名长度07C0:044E C606B00400mov byte ptr[04B0],00;置目录项标记,查找时检查是否为文件07C0:045390nop07C0:0454E899FD call01F0;开始搜索07C0:0457720C jb0465;如果没有找到;将找到的指定文件读出来07C0:0459E861FF call03BD;取出起始扇区和字节数07C0:045C FF7604push word ptr[bp+04]07C0:045F E81FFF call0381;读取扇区07C0:046283C402add sp,000207C0:04655D pop bp07C0:0466C3ret;代码结束,开始数据区07C0:0467DW0000,00000;保存中断08的原地址07C0:046B DW0000;延时计数器;此处存放磁盘扩展读结构07C0:046D DB00;结构尺寸07C0:046E DB00;保留07C0:046F DB00;要读取的扇区数07C0:0470DB00;保留07C0:0471DW0000,0000;读取数据的目标地址07C0:0475DD00;开始逻辑扇区07C0:047A DW0000;保留07C0:047D DW0000;段处理标记,为零不需处理07C0:047E DB"SETUPLDR.BIN"07C0:048A DB"BOOTFIX.BIN"07C0:0495DB"I386"07C0:0499DB0000;磁盘号07C0:049A DW000007C0:049C DW0000;开始逻辑扇区号07C0:049E DW000007C0:04A0DW0000;读取字节数;此处存放读盘操作的临时数据07C0:04A2DW0000,0000;总扇区数07C0:04A6DW0000;数据区的段地址07C0:04A8DW0000,0000;开始逻辑扇区号07C0:04AC DW0000;扇区数07C0:04AD DW0000;搜索字符串地址07C0:04AF DW0000;长度07C0:04B0DB00;目录项标记,为1表示查找子目录07C0:04B1DB0007C0:07FE DB55,AA。
dos常用命令详细讲解
在DOS中,常用命令包括以下几种:
1. dir:显示指定路径上所有文件或目录的信息。
格式为dir [盘符:][路径][文件名] [参数],参数包括/w(宽屏显示)、/p(分页显示)、/a(显示具有特殊属性的文件)、/s(显示当前目录及其子目录下的所有文件)。
2. cd:进入指定目录。
格式为cd [路径],cd命令只能进入当前盘符中的目录,其中“cd\”为返回到根目录,“cd..”为返回到上一层目录。
3. md:建立目录。
格式为md [盘符][路径],表示在当前盘符下建立一个名为temp的目录。
4. attrib:显示、设置或删除指派给文件或目录的只读、存档、系统以及隐藏属性。
如果在不含参数的情况下使用,则attrib 会显示当前目录中所有文件的属性。
可以通过+r设置只读属性,-r清除只读属性;+a设置存档文件属性,-a清除存档文件属性;+h设置隐藏属性,-h清除隐藏属性。
5. cls:清除显示在命令提示符窗口中的所有信息,并返回空窗口,即“清屏”。
6. exit:退出当前命令解释程序并返回到系统。
这些命令都是在DOS环境下常用的命令,对于操作系统的使用和文件管理都非常重要。
主引导扇区——精选推荐
主引导扇区
硬盘0⾯,0道,1扇区,供512个字节,称为主引导扇区。
如果计算机是设置为从硬盘启动,
那么,BIOS将完成基本⼯作前要做的最后⼀件事,就是读取引导扇区,并将它加载到内存地址0x0000:0x7c00处(也就是物理地址0x07c00),
然后⼀个jmp指令跳转到该地址处,接着执⾏。
但是引导扇区必须是有效的才⾏
⼀个有效的主引导扇区,最后两个字节必须为0x55,0xAA。
书作者说不知道为什么是要加载到0x07c00这个地址,我也不知道。
⼀般来说,主引导扇区是由操作系统负责的,
正常情况下,⼀段精⼼编写的主引导扇区代码,将检测⽤来启动计算机的操作系统,并计算出它所在的硬盘位置,
然后它把操作系统的⾃举代码加载到内存,也⽤jmp指令跳转到那⾥继续执⾏,知道操作系统完全启动,
主引导扇区⽰例代码:
; 4-2.asm
mov ax,0xb800
mov ds,ax
mov byte [0x00],'a'
mov byte [0x02],'s'
mov byte [0x04],'m'
jmp $
times 510-($-$$) db 0
db 0x55,0xaa
;最后两⾏必须有,⼀个负责填充,⼀⾏负责有效性检验使⽤
;书上给的代码没有最后两⾏
-----------------------------------------------------
书4.1.5 ⼀切从主引导扇区开始
书5.2 欢迎来到住引导扇区。
DOS引导扇区代码详解
DOS引导扇区代码详解Page ,132TITLE BOOT SECTOR 1 OF TRACK 0 - BOOT LOADER;/*; * Microsoft Confidential; * Copyright (C) Microsoft Corporation 1991; * All Rights Reserved.; */; Rev 1.0 ChrisP, AaronR and others. 2.0 format boot;; Rev 3.0 MarkZ PC/AT enhancements; 2.50 in label; Rev 3.1 MarkZ 3.1 in label due to vagaries of SYSing to IBM drive Ds; This resulted in the BPB being off by 1. So we now trust; 2.0 and 3.1 boot sectors and disbelieve 3.0.;; Rev 3.2 LeeAc Modify layout of extended BPB for >32M support; Move PHYDRV to 3rd byte from end of sector; so that it won have to be moved again; FORMAT and SYS count on PHYDRV being in a known location;; Rev. 3.3 D.C. L. Changed Sec 9 EOT field from 15 to 18. May 29, 1986.;; Rev 3.31 MarkT The COUNT value has a bogus check (JBE) to determine; if weve loaded in all the sectors of IBMBIO. This will; cause too big of a load if the sectors per track is high; enough, causing either a stack overflow or the boot code; to be overwritten.;; Rev 4.00 J. K. For DOS 4.00 Modified to handle the extended BPB, and; 32 bit sector number calculation to enable the primary; partition be started beyond 32 MB boundary.;;; The ROM in the IBM PC starts the boot process by performing a hardware; initialization and a verification of all external devices. If all goes; well, it will then load from the boot drive the sector from track 0, head 0,; sector 1. This sector is placed at physical address 07C00h. The initial; registers are set up as follows: CS=DS=ES=SS=0. IP=7C00h, SP=0400H.;; The code in this sector is responsible for locating the MSDOS device drivers; (IBMBIO) and for placing the directory sector with this information at; physical address 00500h. After loading in this sector, it reads in the; entirety of the BIOS at BIOSEG:0 and does a long jump to that point.;; If no BIOS/DOS pair is found an error message is displayed and the user is; prompted to reinsert another disk. If there is a disk error during the; process, a message is displayed and things are halted.;; At the beginning of the boot sector, there is a table which describes the; MSDOS structure of the media. This is equivalent to the BPB with some; additional information describing the physical layout of the driver (heads,; tracks, sectors);;============================================================================== ;REVISION HISTORY:;AN000 - New for DOS Version 4.00 - J.K.;AC000 - Changed for DOS Version 4.00 - J.K.;AN00x - PTM number for DOS Version 4.00 - J.K.;============================================================================== ;AN001; d52 Make the fixed positioned variable "CURHD" to be local. 7/6/87 J.K.;AN002; d48 Change head settle at boot time. 7/7/87 J.K.;AN003; P1820 New message SKL file 10/20/87 J.K.;AN004; D304 New structrue of Boot record for OS2. 11/09/87 J.K.;AN005; Changed version to 5.0 03/08/90 E.A.;AN006; Changed to remove MSLOAD in first cluster restriction 04/23/90 J.H.;============================================================================== ORIGIN EQU 7C00H ; Origin of bootstrap LOADERBIO_SEG EQU 70H ; Destingation segment of BIOSBIO_OFFSET EQU 700H ; Offset of biosSECTOR_SIZE EQU 512 ; Sector size in bytesDIR_ENTRY_SIZE EQU 32 ; Size of directory entry in bytesDIR_OFF EQU 500hIBM_LOAD_SIZE EQU 3 ;J.K. Size of IBMLOAD module in sectorsROM_DISKRD EQU 2DSK_PARMS EQU 1EH*4 ;POINTER TO DRIVE PARAMETERS; ========================================================================== include version.incinclude dirent.inc; ========================================================================== SEGBIOS SEGMENT AT BIO_SEG; Define the destination segment of the BIOS, including the; initialization labelBIOS LABEL BYTESEGBIOS ENDS; ========================================================================== CODE SEGMENTASSUME CS:CODE,DS:NOTHING,ES:NOTHING,SS:NOTHINGORG ORIGINPublic $START$START:; WARNING -- Don change this to a short jmpjmp Main ; Jump to start of code; ==========================================================================; Start of BPB area of the boot recordIF IBMCOPYRIGHTDB "IBM "ELSEDB "MSDOS"ENDIF; BUGBUG -- 7 Dec 1992 -- chuckst -- changed version back to 5.0 to; avoid bug in PC-TOOLS DISKFIXOsVersion DB "5.0" ; DOS version numberBytesPerSector DW SECTOR_SIZE ; Size of a physical sectorSecsPerClust DB 8 ; Sectors per allocation unitReservedSecs DW 1 ; Number of reserved sectorsNumFats DB 2 ; Number of fatsNumDirEntries DW 512 ; Number of direc entriesTotalSectors DW 4*17*305-1 ; Number of sectors - number of hidden; sectors (0 when 32 bit sector number)MediaByte DB 0F8H ; MediaByte byteNumFatSecs DW 8 ; Number of fat sectorsSecPerTrack DW 17 ; Sectors per trackNumHeads DW 4 ; Number of drive headsHiddenSecs DD 1 ; Number of hidden sectorsBigTotalSecs DD 0 ; 32 bit version of number of sectorsBootDrv DB 80hCurrentHead DB 0h ; Current HeadExtBootSig DB 41SerialNum DD 0VolumeLabel DB NO NAMEFatId DB FAT12; Danger If not 32 bit sector number calculation,; FORMAT should set the value of HiddenSecsHigh and; BigTotalSectors to 0PUBLIC uDatauData LABEL BYTE;Equates to allow access to;storage where Main is nowSec9 EQU BYTE PTR uData+0 ;11 byte diskette parm. tableBiosLow EQU WORD PTR uData+11BiosHigh EQU WORD PTR uData+13CurTrk EQU WORD PTR uData+15CurSec EQU BYTE PTR uData+17DirLow EQU WORD PTR uData+18DirHigh EQU WORD PTR uData+20; ========================================================================= ; First thing is to reset the stack to a better and more known; place. The ROM may change, but wed like to get the stack; in the correct place.MAIN:cli ;Stop interrupts till stack okxor AX,AXmov SS,AX ;Work in stack just below this routineASSUME SS:CODEmov SP,ORIGINpush SSpop ESASSUME ES:CODE; We copy the disk parameter table into a local area. We scan; the table above for non-zero parameters. Any we see get; changed to their non-zero values. We copy the disk parameter; table into a local area (overlayed into the code)mov BX,DSK_PARMSlds SI,DWORD PTR SS:[BX] ; get address of disk tablepush DS ; save original vector for possiblepush SI ; restorepush SSpush BXmov DI,OFFSET Sec9mov CX,11cldrepz movsbpush ESpop DS ; DS = ES = code = 0.assume DS:CODE; Set the head settle time to 15ms because we don have room; to do a disk retry and then set sectors per from the value; in the BPBmov BYTE PTR [DI-2], 0fh ; Head settle timemov CX, SecPerTrackmov BYTE PTR [DI-7], cl ; End of Trackmov [BX+2],AX ; Place in new disk parametermov [BX],offset Sec9 ; table vector; We may now turn interrupts back on. Before this, there is; a small window when a reboot command may come in when the ; disk parameter table is garbagesti ; Interrupts OK nowint 13h ; Reset the disk system just in casejc CkErr ; any thing funny has happened.; The system is now prepared for us to begin reading.; First, determine logical sector numbers of the start of the; directory and the start of the data area.xor AX,AXcmp TotalSectors,AX ; 32 bit calculation?je Dir_Contmov CX,TotalSectorsmov WORD PTR BigTotalSecs,CX ; BigTotalSecsDir_Cont:mov AL,NumFats ;Determine sector dir starts onmul NumFatSecs ;DX;AXadd AX,WORD PTR HiddenSecsadc DX,WORD PTR HiddenSecs[2]add AX,ReservedSecsadc DX,0; DX:AX = NumFats * NumFatSecs + ReservedSecs + cSecHid mov [DirLow],AXmov [DirHigh],DXmov [BiosLow],AXmov [BiosHigh],DX; Take into account size of directory (only know number; of directory entries)mov AX,DIR_ENTRY_SIZE ; bytes per directory entrymul NumDirEntries ; convert to bytes in directorymov BX,BytesPerSector ; add in sector sizeadd AX,BXdec AX ; decrement so that we round updiv BX ; convert to sector numberadd [BiosLow],AX ; Start sector # of Data areaadc [BiosHigh],0; We load in the first directory sector and examine it to; make sure the the BIOS and DOS are the first two directory ; entries. If they are not found, the user is prompted to; insert a new disk. The directory sector is loaded into 00500h mov BX,DIR_OFF ; sector to go in at 00500hmov DX,[DirHigh]mov AX,[DirLow] ; logical sector of directorycall DoDiv ; convert to sector, track, headjc CkErr ; Overflow? BPB must be wrong!!mov al, 1 ; disk read 1 sectorcall DoCall ; do the disk readjb CkErr ; if errors try to recover; Now we scan for the presence of BIOS file.mov DI,BXmov CX,11mov SI,OFFSET Bio ; point to "ibmbio com"repz cmpsb ; see if the samejnz CkErr ; if not there advise the user; Found the BIOS. Check the second directory entry.; SI will already point to "MSDOS SYS"if first compare; was successfullea DI,[BX+20h];** mov SI,OFFSET Dosmov CX,11repz cmpsbjz DoLoad; There has been some recoverable error. Display a message ; and wait for a keystroke.CkErr: mov SI,OFFSET SysMsg ; point to no system message ErrOut:call Write ; and write on the screenxor AX,AX ; wait for responseint 16h ; get character from keyboardpop SI ; reset disk parameter table back topop DS ; rompop [SI]pop [SI+2]int 19h ; Continue in loop till good diskLoad_Failure:pop ax ;adjust the stackpop axpop axjmp short CkErr ;display message and reboot.; We now begin to load the BIOS in.; All we have to do is just read is multiply the BioStartClus; by SecsPerClust to find the logical sector for the start; of the BIOS file. When this value is added to the double; word BiosHigh:BiosLow we get the absolute sector offset; for the start of the file and then read the sectors; contiguously IBM_LOAD_SIZE times. We here assume that; IBMLOAD module is contiguous. Currently we estimate that; IBMLOAD module will not be more than 3 sectors.DoLoad:mov AX,[BX].DIR_FIRST ; AX = BIOS starting clusterdec AX ; Subtract first 2 reserved clustersdec AXmov BL,SecsPerClust ; BX = Sectors per clusterxor BH,BHmul BX ; DX:AX = first logical sector of biosadd AX,[BiosLow] ; Add absolute start sectoradc DX,[BiosHigh] ; DX:AX = Absolute bios sector offsetmov BX,BIO_OFFSET ;offset of ibmbio(IBMLOAD) to be loaded.mov CX,IBM_LOAD_SIZE ;# of sectors to read.Do_While:push AXpush DXpush CXcall DoDiv ; DX:AX = sector number.jc Load_Failure ; Adjust stack. Show error messagemov al, 1 ; Read 1 sector at a time.; This is to handle a case of media; when the first sector of IBMLOAD is the; the last sector in a track.call DoCall ; Read the sector.pop CXpop DXpop AXjc CkErr ; Read error?add AX,1 ; Next sector number.adc DX,0add BX,BytesPerSector ; Adjust buffer address.loop Do_While; ========================================================================= ; Main read-in loop.; ES:BX points to area to read.; Count is the number of sectors remaining.; BIOS$ is the next logical sector number to read;; CurrentHead is the head for this next disk request; CurTrk is the track for this next request; CurSec is the beginning sector number for this request;; AX is the number of sectors that we may read.;; ========================================================================= ;; IBMINIT requires the following input conditions:;; DL = INT 13 drive number we booted from; CH = media byte; IBMBIO init routine should check if the boot record is the; extended one by looking at the extended_boot_signature.; If it is, then should us AX;BX for the starting data sector number.;========================================================================= DISKOK:mov CH,MediaBytemov DL,BootDrvmov BX,[BiosLow] ; J.K.I1.Get bios sector in bxmov AX,[BiosHigh] ; J.K.I1.jmp FAR PTR Bios ;CRANK UP THE DOSWRITE:lodsb ;GET NEXT CHARACTERor AL,AL ;Clear the high bitjz EndWr ;ERROR MESSAGE UP, JUMP TO BASICmov AH,14 ;WILL WRITE CHARACTER & ATTRIBUTEmov BX,7 ;ATTRIBUTEint 10h ;PRINT THE CHARACTERjmp Write; Convert a logical sector into Track/sector/head.; DX;AX has the sector number. Because of not enough space, we; are going to use Simple 32 bit division here.; Carry set if DX;AX is too big to handle.DODIV:cmp DX,SecPerTrack ; To prevent overflowjae DivOverFlow ; Compare high word with the divisor.div SecPerTrack ; AX = Total tracks, DX = sector numberinc DL ; We assume SecPerTrack < 255 & DH=0; curSec is 1-based.mov CurSec, DL ; Save itxor DX,DXdiv NumHeadsmov CurrentHead,DL ;Also, NumHeads < 255.mov CurTrk,AXclcretDivOverFlow:stcEndWR:ret; ========================================================================= ;; Issue one read request. ES:BX have the transfer address,; AL is the number of sectors.;; ========================================================================= DOCALL:mov AH,ROM_DISKRD ;=2mov DX,CurTrkmov CL,6shl DH,CLor DH,CurSecmov CX,DXxchg CH,CLmov DL, BootDrvmov DH, CurrentHeadint 13hret; ========================================================================= include boot.cl1; ========================================================================= IF IBMCOPYRIGHTBio DB "IBMBIO COM"Dos DB "IBMDOS COM"ELSEBio DB "IO SYS"Dos DB "MSDOS SYS"ENDIF; ========================================================================= Free EQU (SECTOR_SIZE - 4) - ($-$start)if Free LT 0%out FATAL PROBLEM:boot sector is too large.ERRendiforg origin + (SECTOR_SIZE - 2)db 55h,0aah ; Boot sector signature; ========================================================================= CODE ENDSENDDOS引导扇区代码详解如果从软盘起动,则Dos引导程序被ROM BIOS直接加载到内存,若从硬盘起动,则被硬盘的主引导程序加载.不过都是被加载到内存的绝对地址0000:7C00H处.因此,Dos引导程序的第⼀条指令的地址⼀定是0000:7C00H.Dos引导程序所做的事情如下:1>调整堆栈位置2>修改并⽤修改后的磁盘参数表来复位磁盘系统3>计算根⽬录表的⾸扇区的位置及IO.SYS的扇区位置4>读⼊根⽬录表的⾸扇区5>检查根⽬录表的开头两项是否为IO.SYS及MSDOS.SYS6>将IO.SYS⽂件开头三个扇区读⼊内存0000:0700H处7>跳到0000:0700H处执⾏IO.SYS,引导完毕上述每⼀步若出错,则显⽰"Non system disk or disk error..."信息,等⽤户按任⼀键后试图重新起动.下⾯的Dos引导程序是从硬盘上得来的,显⽰MSDOS5.0,但Dos的ver命令报告的是6.22版.FAT表⾃然是16位的.说明:(DX) 表⽰寄存器DX的值逻辑扇区号以0⾯0道1扇区作为逻辑0扇区,⽽不是以Dos引导扇区为逻辑0扇区,当然,对软盘来说⼆者是相同的,对硬盘则不同⾯号即磁头号磁道号即柱⾯号(对硬盘)物理扇区号由⾯号,磁道号,扇区号三者共同指定偏移机器码符号指令说明============================================================================ ==0000 EB3C JMP 003E ;跳过数据区;以下数据是⼚商OEM信息和磁盘BPB表0000 90 4D 53 44 4F 53-35 2E 30 00 02 08 01 00 .MSDOS5.0.....0010 02 00 02 00 00 F8 CC 00-3F 00 10 00 3F 00 00 00 ........?...?...0020 F1 59 06 00 80 00 29 E3-0B 3F 26 53 4C 4D 20 20 .Y....)..?&SLM0030 20 20 20 20 20 20 46 41-54 31 36 20 20 20 FAT16------------------------------------------------------------------------------003E FA CLI003F 33C0 XOR AX,AX0041 8ED0 MOV SS,AX0041 8ED0 MOV SS,AX0043 BC007C MOV SP,7C00 ; 初始化堆栈0046 16 PUSH SS0047 07 POP ES ;(ES)=0000H0048 BB7800 MOV BX,0078 ;1EH 号中断向量的地址为0000:0078H004B 36 SS: ;(SS)=0000H004C C537 LDS SI,[BX] ;取1EH号中断向量的内容存⼊DS:SI004E 1E PUSH DS ;该中断向量指向⼀个11字节的磁盘参;数表004F 56 PUSH SI ;取到后压⼊堆栈中保存0050 16 PUSH SS0051 53 PUSH BX ;保存地址0000:0078H0052 BF3E7C MOV DI,7C3E ;7C3E-7C00=003EH,即偏移003EH,以下;类推0055 B90B00 MOV CX,000B ;磁盘参数表共11字节0058 FC CLD0059 F3 REPZ005A A4 MOVSB ;将磁盘参数表复制到0000:7C3EH处005B 06 PUSH ES005C 1F POP DS ;(DS)=0000H005D C645FE0F MOV BYTE PTR [DI-02],0F ;修改参数表中"磁头定位时间"0061 8B0E187C MOV CX,[7C18] ;从BPB中取"每磁道扇区数"0065 884DF9 MOV [DI-07],CL ;修改参数表中"每磁道扇区数"0068 894702 MOV [BX+02],AX ;(AX)=0000H,修改1EH号中断向量;(段址)006B C7073E7C MOV WORD PTR [BX],7C3E ;修改1EH号中断向量(偏移),这;样1EH号006F FB STI ;中断向量的内容为0000:7C3EH,指向新的磁盘参;数表0070 CD13 INT 13 ;⽤新的磁盘参数表来复位磁盘0072 7279 JB 00ED ;出错则转出错处理-------------------------------------------------------------------------------; 下⾯⼀段程序计算扇区位置0074 33C0 XOR AX,AX0076 3906137C CMP [7C13],AX ;偏移0013H处是Dos分区的总扇区数007A 7408 JZ 0084 ;为零表⽰⼤硬盘?007C 8B0E137C MOV CX,[7C13] ;不为0则取出来放到偏移0020H处0080 890E207C MOV [7C20],CX ;这个值本程序未⽤,似乎为IO.SYS准备;的0084 A0107C MOV AL,[7C10] ;取FAT表的个数0087 F726167C MUL WORD PTR [7C16] ;乘以⼀个FAT表所占的扇区数008B 03061C7C ADD AX,[7C1C] ;加上Dos分区前的扇区数(隐藏扇数,低;位)008F 13161E7C ADC DX,[7C1E] ; ⾼;位)0093 03060E7C ADD AX,[7C0E] ;加上Dos分区内的保留扇区数(低位) 0097 83D200 ADC DX,+00 ; (⾼位)009A A3507C MOV [7C50],AX ;根⽬录表的⾸扇的逻辑扇区号(低位) 009D 8916527C MOV [7C52],DX ; (⾼位)00A1 A3497C MOV [7C49],AX ;此处放IO.SYS的⾸扇的逻辑扇区号(低;位)00A4 89164B7C MOV [7C4B],DX ; (⾼;位)00A8 B82000 MOV AX,0020 ;根⽬录表中每项占32字节00AB F726117C MUL WORD PTR [7C11] ;乘以根⽬录表中的项数00AF 8B1E0B7C MOV BX,[7C0B] ;取"每扇区的字节数"00B3 03C3 ADD AX,BX ;这两条指令是为了取整00B5 48 DEC AX00B6 F7F3 DIV BX ;除以每扇字节数,得到根⽬录所占扇区;数00B8 0106497C ADD [7C49],AX ;得到根⽬录表后⾸扇的逻辑扇区号(低;位)00BC 83164B7C00 ADC WORD PTR [7C4B],+00 ; (⾼;位)-------------------------------------------------------------------------------;下⾯⼀段程序在根⽬录表中找系统⽂件IO.SYS和MSDOS.SYS00C1 BB0005 MOV BX,0500 ;内存缓冲区的偏移值00C4 8B16527C MOV DX,[7C52] ;取根⽬录表的⾸扇的逻辑扇区号(⾼;位)00C8 A1507C MOV AX,[7C50] ; (低;位)00CB E89200 CALL 0160;将逻辑扇区号转换为物理扇区号00CE 721D JB 00ED ;出错则转出错处理00D0 B001 MOV AL,0100D2 E8AC00 CALL 0181 ;读⼀个扇区到内存(根⽬录的⾸扇)00D5 7216 JB 00ED ;出错处理00D7 8BFB MOV DI,BX ;内存缓冲区的⾸址00D9 B90B00 MOV CX,000B ;⽐较11个字节00DC BEE67D MOV SI,7DE6 ;偏移01E6处是串"IO SYS",长11;字节00DF F3 REPZ00E0 A6 CMPSB ;看第⼀项是否为IO.SYS00E1 750A JNZ 00ED ;不是则出错00E3 8D7F20 LEA DI,[BX+20] ;跳过32字节就指向第⼆项00E6 B90B00 MOV CX,000B ;⽐较11个字节00E9 F3 REPZ00EA A6 CMPSB ;看第⼆项是否为MSDOS.SYS00EB 7418 JZ 0105 ;是则两个⽂件都已找到,跳过出错处理------------------------------------------------------------------------------;下⾯⼀段进⾏出错处理00ED BE9E7D MOV SI,7D9E ;偏移019EH处是串"Non system disk. ;.."00F0 E85F00 CALL 0152 ;显⽰字符串00F3 33C0 XOR AX,AX00F5 CD16 INT 16 ;等待任⼀键按下00F7 5E POP SI00F8 1F POP DS ;得到1EH号中断向量的地址0000:0078H00F9 8F04 POP [SI]00FB 8F4402 POP [SI+02] ;恢复1EH号中断向量的内容00FE CD19 INT 19 ;⾃举0100 58 POP AX0101 58 POP AX0102 58 POP AX ;清理堆栈0103 EBE8 JMP 00ED ;再次试图起动------------------------------------------------------------------------------;下⾯读⼊IO.SYS的头3个扇区到内存0000:0700H处0105 8B471A MOV AX,[BX+1A] ;从根⽬录表第⼀项中取IO.SYS的⾸簇;号0108 48 DEC AX0109 48 DEC AX ;⾸簇号减⼆010A 8A1E0D7C MOV BL,[7C0D] ;取每簇的扇区数010E 32FF XOR BH,BH0110 F7E3 MUL BX ;(⾸簇号 - 2)乘以每簇的扇区数0112 0306497C ADD AX,[7C49] ;相加后得到IO.SYS的⾸扇的逻辑扇区;号0116 13164B7C ADC DX,[7C4B]011A BB0007 MOV BX,0700 ;内存缓冲区的偏移值011D B90300 MOV CX,0003 ;循环计数初值,读3个扇区0120 50 PUSH AX ;逻辑扇区号进栈(低位)0121 52 PUSHDX ; (⾼位)0122 51 PUSH CX ;循环计数器进栈0123 E83A00 CALL 0160 ;逻辑扇区号转换为物理扇区号0126 72D8 JB 0100 ;出错处理0128 B001 MOV AL,01012A E85400 CALL 0181 ;读⼀个扇区到内存缓冲区012D 59 POP CX ;循环计数出栈012E 5A POP DX012F 58 POP AX ;逻辑扇区号出栈0130 72BB JB 00ED ;读盘出错处理0132 050100 ADD AX,00010135 83D200 ADC DX,+00 ;下⼀个扇区0138 031E0B7C ADD BX,[7C0B] ;缓冲区指针移动⼀个扇区的⼤⼩013C E2E2 LOOP 0120 ;循环读⼊三个扇区013E 8A2E157C MOV CH,[7C15] ;取"磁盘介质描述",传给IO.SYS 0142 8A16247C MOV DL,[7C24] ;取"系统⽂件所在的驱动器号"0146 8B1E497C MOV BX,[7C49] ;取IO.SYS的⾸扇的逻辑扇区号014A A14B7C MOV AX,[7C4B]014D EA00007000 JMP 0070:0000 ;执⾏IO.SYS,引导完毕------------------------------------------------------------------------------;显⽰字符串的⼦程序0152 AC LODSB ;从串中取⼀个字符0153 0AC0 OR AL,AL0155 7429 JZ 0180 ;为0则已到串尾,返回(共⽤RET指令)0157 B40E MOV AH,0E0159 BB0700 MOV BX,0007015C CD10 INT 10 ;显⽰该字符015E EBF2 JMP 0152 ;循环显⽰下⼀个----------------------------------------------------------------------------;将逻辑扇区号转换为物理扇区号的⼦;程序0160 3B16187C CMP DX,[7C18] ;这两条指令是为了避免第⼆次除法时;除数0164 7319 JNB 017F ;为00166 F736187C DIV WORD PTR [7C18] ;逻辑扇取号除以每道扇区数,商(AX)= ;总磁016A FEC2 INC DL ;道数,余数(DX)再加⼀即为扇区号,因;为扇016C 88164F7C MOV [7C4F],DL ;区号是从1开始的,⽽不是从0开始0170 33D2 XOR DX,DX0172 F7361A7C DIV WORD PTR [7C1A] ;总磁道数(AX)再除以⾯数,所得的0176 8816257C MOV [7C25],DL ;余数(DX)=⾯号(即磁头号)017A A34D7C MOV [7C4D],AX ;商(AX)=磁道号017D F8 CLC017E C3 RET ;正常返回017F F9 STC0180 C3 RET ;异常返回-----------------------------------------------------------------------------;读⼀个扇区的⼦程序0181 B402 MOV AH,02 ;读功能调⽤0183 8B164D7C MOV DX,[7C4D] ;需要的⼊⼝参数如下:0187 B106 MOV CL,06 ;(DL)=驱动器号0189 D2E6 SHL DH,CL ;(DH)=⾯号018B 0A364F7C OR DH,[7C4F] ;(CH)=磁道号018F 8BCA MOV CX,DX ;(CL)=扇区号(第6,7位为磁道号的⾼2;位)0191 86E9 XCHG CH,CL ;(AL)=要读的扇区数0193 8A16247C MOV DL,[7C24] ;(ES:BX)=缓冲区⾸址0197 8A36257C MOV DH,[7C25]019B CD13 INT 13019D C3 RET-------------------------------------------------------------------------------0190 0D 0A ..01A0 4E 6F 6E 2D 53 79 73 74-65 6D 20 64 69 73 6B 20 Non-System disk 01B0 6F 72 20 64 69 73 6B 20-65 72 72 6F 72 0D 0A 52 or disk error..R01C0 65 70 6C 61 63 65 20 61-6E 64 20 70 72 65 73 73 eplace and press01D0 20 61 6E 79 20 6B 65 79-20 77 68 65 6E 20 72 65 any key when re01E0 61 64 79 0D 0A 00 49 4F-20 20 20 20 20 20 53 59 ady...IO SY01F0 53 4D 53 44 4F 53 20 20-20 53 59 53 00 00 55 AA SMSDOS SYS..U.。
DOS主引导扇区分析
;将一个字符调入AL
064C CMP AL,00
;是否为字符串结束标志?
064E JZ 065B
;字符串结束标志,字符串显示完毕
0650 PUSH SI
;下一个要显示的字符的指针
0651 MOV BX,0007
;以黑底白字显示
0654 MOV AH,0E
;显示一个字符
0656 INT 10
;BIOS调用
;指向分区信息表
0620 MOV BL,04
;最多4个分区信息表
0622 CMP BYTE PTR [SI],80 ;该分区是否为活动分区?
0625 JZ 0635
;该分区为活动分区,跳转
0627 CMP BYTE PTR [SI],00
062A JNZ 0648
062C ADD SI,+10
;指向分区信息表的下一项
062F DEC BL
;是否已经没有分区信息了?
0631 JNZ 0622
;还有分区信息,检查下一项
0633 INT 18
;没有分区信息了,没有可以启动的分区,启动ROM BASIC
;找到了活动分区,开始读取活动分区的分区引导程序
0635 MOV DX,[SI]
;DH中为该分区磁头号,DL=80h
0637 MOV CX,[SI+02]
2、主引导扇区的结构
要注意,硬盘的磁头和柱面都是从0开始数的,但是扇区是从1开始数的,通常我们硬盘上的这个0磁头、0柱面、1扇区称作第 一个物理扇区,一般我们把这个主引导扇区分成三部分,第一部分叫MBR(Master Boot Rocord),主引导记录,这部分有446个字 节,从0--445(0x00--0x1BD);另一部分叫做DPT(Disk Partition Table),磁盘分区表,占这个扇区中的其余64个字节,从446-509(0x1BE--0x1FD);第三部分是一个结束标志,占两个字节,从510--511(0x1FE--0x1FF),其正常内容应该是0xAA55(0x55在低 地址字节)。
引导扇区代码
引导扇区代码(纯属娱乐)org 7c00h ; 告诉编译器程序加载到7c00处mov ax, csmov ds, axmov es, axcall DispStr ; 调用显示字符串例程; 加载内核jmp $ ; 无限循环DispStr:mov ah,6 ;初始化屏幕mov al,0mov cx,0mov dh,0xffmov dl,0xffint 10hmov ax, BootMessagemov bp, ax ; ES:BP = 串地址mov cx, 31 ; CX = 串长度mov ax, 01301h ; AH = 13, AL = 01hmov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮) mov dx, 0int 10h ; 10h 号中断mov ah,00hint 16hmov ah,6 ;初始化屏幕mov al,0mov cx,0mov dh,0xffmov dl,0xffint 10hmov ax, Messagemov bp, ax ; ES:BP = 串地址mov cx, 41 ; CX = 串长度mov ax, 01301h ; AH = 13, AL = 01hmov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮) mov dx, 0int 10h ; 10h 号中断mov ah,00hint 16hmov ax,0x0013 ;显卡切换入640*480 256色图形工作模式int 10hmov ax,0c0ch ;绘制直角三角形mov si,10mov cx,90mov di,cxs: mov bh,0mov cx,10mov dx,siint 10hsub di,1inc simov cx,diloop smov di,10mov cx,90mov si,cxa: mov bh,0mov cx,dimov dx,10int 10hsub si,1inc dimov cx,siloop amov dx,simov cx,100mov di,cxb: mov bh,0mov cx,dimov dx,siint 10hsub di,1inc simov cx,diloop bretBootMessage: db "Loading Simo OS...demo:keybored"Message: db "Do you want to reboot now [y/yes] [n/no]?"Key: db 0times 444-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为446字节(为了防止覆盖分区表)dw 0xaa55 ; 结束标志终端执行:nasm xxx.asm -o boot.bindd if=boot.bin of=/dev/sdb。
常用DOS命令参数的中文详解
常用DOS命令参数的中文详解LT常用DOS命令参数的中文详解一、DIR 命令的格式:dir [D:][PATH][NAME][[/A][:attrib]][/o:[sorted][/s][/b][/l][/c[h] (1)dir /a:attrib 缺省包含所有文件(系统文件.隐含文件)attrib[:][h/-h]只显示隐含文件或非隐含文件.[r/-r]只显示只读文件或非只读文件[s/-s]只显示系统文件或非系统文件[a/-a]只显示要归档文件或非归档文件(2)/o[:]sorted:缺省完全按字母顺序,子目录显示在文件之前/o[n/-n]:按字母顺序或按文件名顺序/反向显示[e/-e]:按扩展名字母顺序/反向显示[d/-d]:按时间顺序/反向显示[s/-s]:按大小从大到小或/反向显示[g/-g]:按子目录先于文件或文件先于子目录(3)/s 参数:对当前目录及其子目录中所有文件进行列表列名ir /s/a/o:n c:\>PRN将c盘上的所有子目录和文件按隶属关系并根据子目录和文件字母顺序打印输出(4)/B 参数:将只显示文件名与扩展名(5)/L 参数:将全部用小写字母对文件或子目录进行列表训练:dir /a 列当前目录所有文件(含隐含及系统文件)dir /ah 列隐含文件(包含子目录(隐含的) dir /a-hdir /as 列系统文件dir /a-sdir /ad 列子目录dir /a-ddir /o 按字母顺序dir /B 只显示文件名与扩展名二、attrib [+r|-r] [+a|-a] [+s|-s] [+h|-h] [d: ] [name] [/s] 缺省attrib name 显示文件的(文件)属性attrib io.sys (或子目录)shr c:\ io.sys 指定为系统(s) 隐含(h) 只读(r)文件也可以attrib *.sys 显示扩展名为sys的文件属性参数[+r|-r] 将文件属性设置或解除只读属性[+a|-a] 将文件属性设置或解除归档属性[+h|-h] 将文件属性设置或解除隐含属性(尤其对子目录也起作用) /s 参数将当前及当前子目录下的所有文件均起作用可以用来查找文件例子:attrib news86 列news86的文档属性attrib +r report.txt 设置为只读attrib -s -h record.txtattrib +a a:*.*attrib -a a:*.bakxcopy a: b: /a 将A盘上的所有标志为"归档"属性的文件拷到B盘xcopy a: b: /m 将A盘上的所有文件拷到B盘后并移去归档属性三、cd 介绍: cd...返回上二级目录"."代表当前目录"."代表父目录cd ..\..返回到上级目录的父目录(祖目录)cd A:\ 将A盘的当前目录改为根目录cd A:\xx 将A盘的当前目录改为子目录xx下cd ..\98 先返回父目录,再进入父目录下的98子目录cd ..返回到父目录cd\98 进入根目录下的98子目录四、copy [/y][/-y][/v][ /B]copy /y 不加提示,对所有文件加以覆盖/-y 加以提示,对所有文件(yes或no提问)/v 拷贝以后加以校验/B 按二进制进行显示copy w1.wps con/b 可以将wps文件在屏幕上显示,而不必进入wps状态copy ..\98 将父目录下的98子目录下的所有文件全拷到当前子目录copy .\97 当当前目录下的97子目录下文件全部拷到当前目录copy . c:\ 将当前目录下的所有文件拷到c盘根目录. 意味着*.* 文件copy nul a.abc 将a.abc 文件清空(文件长度改为0)copy 文件名+con 向文本文件中追加命令或内容copy con 文件名创立文本文件(F6存盘退出)copy con prn 检测打印机的开关五、xcopy命令xcopy [source] [d ate] [/p] [/s] [/e] [/v] [/y]xcopy [d ate] xcopy a:b:\ /d:08/18/98/s/v 拷贝98.08.18年后的文件xcopy [/p] 提示创立子目录xcopy [/s] 连带子目录一起拷贝. 注意:假设目标盘上不存在此子目录,而在目标盘的结束符又不以"\"为结束,那么将提示:does destination specify a file name or directory name on the target [f=file,d=directory]?在目标盘上创立文件[按下]还是创立子目录[按下d] ?应选择d键xcopy[/v] 带较验*1) xcopy 不拷贝系统和隐含文件,应先予以修改属性再拷贝xcopy [/y] 覆盖时是否有提示, /y 不带提示假设省略目标盘或子目录名,那么拷贝到当前目录下六、del /p加/p 可以在删除前是否提示如del后加子目录名,那么将子目录下所有文件(隐含.系统.只读文件除外)全删除, 加/p那么可以确认.七、undelete [name] /au不加提示地将所有满足条件的文件恢复(能够恢复的),并将首字母置成"#",假设已存在,那么按"# % & 0 1 2-9 a-z"顺序加上.如:undelete *.dbf/au 将扩展名为"dbf"的文件全恢复,并以"#"开头,作为文件名, /list 仅列出可恢复的文件,而不恢复undelete /load 将undelete装入内存/unload 将undelete卸出内存/s[drive]对指定驱动器进行监测管理undelete/sc将undelete驻留内存,?并创立一个隐含的sentry 子目录对c盘删除的文件进行管理undelete/ds 恢复相应恢复命令可以用undelete即可完整恢复出文件名(非常完整)最常用undelete *.*deltree /y [drive ath]deltree 删除子目录及文件,尽管有些文件是系统文件或隐含文件它可以带有通配符,带有通配符时,它将删除符合条件的文件及子目录如:?undelete *.dbf/au 将扩展名为"dbf"的文件全恢复,并以"#"开头作为文件名./list 仅列出可恢复的文件,而不作恢复操作.undelete/load 将undelete 装入内存./unload将undelete 卸出内存./s[drive] 对指定的驱动器进行监视管理.undelete/sc 将undelete 驻留内存,并创立一个隐含的sentry子目录对C盘删除的文件进行管理.相应恢复命令可以用undelete/ds 即可完整恢复出文件名(很完善). 最常用的是undelete *.*八、deltree /y [drive ath]deltree 删除子目录及文件,尽管有些文件是系统或隐含的.它可以带有通配符,这时它将删除符合条件的文件或子目录.如:存在L1文件,L2子目录,L3文件,L4子目录deltree L*.* 将删除以上所有的文件和子目录,但在删除前加以确认,假设不删除,可以输入"N"./y 参数是在删除时不加以确认就进行操作的.它删除的文件可以用undelete恢复,?但不能恢复子目录及其下的文件,可以用特殊工具.如NORTON 8.0 等.假设提前使用了undelete/s,?那么可以在sentry子目录下找到完整的文件,但名已经改变了.九、dos=high[|low[umb|noumb]]dos=high,umb 那么dos将自身装入高端内存(high)并能管理上位内存(umb). noumb 那么不管理上位内存.在写入dos=high及umb 前应装入device=himem.sys为了将程序或驱动程序装入上位内存,必须使用dos=umb,可省出大局部常规内存.可以在config.sys的任何位置写上dos=high,umb假设显示hma not avoiable 或load down low 那么说明不能使用高端内存.十、doskey 记录以前敲过的dos命令,可以用F7来显示,用"↑↓"来选择,用F9来输入选择的命令号.doskey/restall 重新装入一次,以前的命令行撤消.doskey/history 显示内存中所有的命令,可以">"显示到其它文件中,缩写"/H". doskey dir=cls 那么击入dir等同于cls一样.doskey/macros 可显示所有的宏定义,可使用">"重定义到文件中,可缩写"/M". doskey dir= 可撤消对dir 的宏定义.doskey p=dir$tdir*.exe/p$tdir c:\t$tdir c:\t$*$t为命令的区分符,而$*为命令的结束符doskey/insert(overstrike)?在重新输入命令时,对旧命令的修改是插入还是覆盖状态(默认).十一、emm386.exe提供对扩展内存的管理,使应用程序象使用常规内存一样能够使用它.常见的用法是在config.sys 中device=c:\dos\himem.sysdevice=c:\dos\emm386.exe ramd=64 将DMA 内存数量设置为64Knoems 提供对上位内存的访问,但不提供对扩展内存的访问.应注意的是在windows中最好不要用它,因为windows本身有对扩展内存进行管理的程序.应采用windows中的管理器.十二、fc 命令fc/b dt.dat dt2.dat>b (作二进制代码比拟)比拟两个文件,一般用作存取进度,修改游戏存储文件用.实际代码位置应加上0100 如:0000 05E4:00 67实际用debug -e 修改时应加上0100 即0000 06E4:00 67后面加上重定向文件">P" 可以将比拟结果输出到p文件中.十三、format /q /u /s /n:sectors /f:size /c/q参数:快速格式化,仅扫描文件分配表和根目录区,仅对格式化过的磁盘有效. 使用时应确保格式化过后没有增加新的坏道./u参数:无条件格式化,并且不保存原来盘上的信息,可以防止"unformat"./s参数:格式化为系统盘,也可以使用"sys"命令./f:size size 可以为160 180 320 360 720 1200 1440 2800/n:sector n可以为1 格式为单面盘,容量为160k 180k可以为4 可以在5寸高密驱动器上格式化360k磁盘可以为8 可以在5寸高密驱动器上进行8个扇区的格式化./c 重新测试坏扇区,缺省时如果一个扇区标记为"坏",以后格式时就不在从新测试,仅作标记,使用"/C"时可以从新测试.十四、unformat 命令对用format 格式过,且未用"/u"参数的命令起作用,用它可以来重新修复已经损坏的硬盘分区表,但对网络盘不起作用.unformat drive:[/l][/test][/p]/l 显示每一个被unformat发现的文件和子目录,如果没有这个开关,只显示那些破碎的文件和子目录,可以用ctrl+s 暂停,按任意键继续./test 仅作一个测试,不作实际的修复工作,作模拟过程./p 一边测试一边打印.注:这种方法不能保证修复所有的文件,尤其是格式化后又添加过数据的磁盘.恢复后的文件依次存放在subdir1....2....3等子目录中.十五、interlnk 语法interlnk g=e ,它可以通过串口或并口在两机间进行通讯. 将效劳器端上的e驱动器映射为客户端的g驱动器,以后对客户端而言,所有对g的操作都意味着对效劳器的访问,取消映射的方法为interlnk g=单独输入interlnk 那么显示所有的映射情况.注意:interlnk 必须在装入interlnk.exe 设备驱动程序才可以使用.所用的驱动器符号与config.?sys中lastdrv.exe设置的数目有关.可以作一个一端为25针,另一端为9针的串行线实现,具体接线方式如下:5 - 7 2 - 153 - 2 3 - 137 - 4 4 - 126 - 6 5 - 103 - 3 6 - 118 - 5 15 - 24 - 20 13 - 39针25针12 - 410 - 511 - 625 - 2525针25针十六、interlnk.exe 与intersvr.exeinterlnk.exe 重新定向对于客户驱动器或打印接口的请求到另外的效劳器驱动器或打印机.语法:config.sys 中参加:device=c:\dos\interlnk.exe [drive:n][/noprinter][com][lpt]十七、memmaker[/b][/batch][session][/swap rive]使用memmaker能够优化内存配置,?并将配置写入autoexec.bat和config.sys中. 在这一过程中,需要重新启动几次机器.十八、memitem memcolor memdefault submenu 菜单项选择项include autoexec.bat 中如下: config.sys中如下:path c:\dos;c:\ucdos [menu]doskey menucolor=15,1(前景色15,背景色1)\mouse\mouse menuitem=base_config,this is a basegoto %config% ->选择项menuitem=cced_config,this is a cced选项提示:base_config menudefault=base_config,5goto exit ->跳出缺省为base_config,延迟时间5秒:cced_config [common]c:\dos\smartdrv.exe /l device=c:\dos\himem.sysgoto exit 各项都包含的共同局部:exit ->结束[base_config]device=c:\dos\emm386.exe ramdos=high,umb[cced_config]device=c:\dos\smartdrv.exe/double_bufferinclude=base_config 包含base_config设置可以根据计算机的在不同情况下的配置要求来选择.十九、mscdex.exe 提供对光驱进行读写的程序mscdex/d rive [/D rive][/e][/k][/s][/l:letter]典型:config.sys 中device=c:\cdrom\cdrom.sys /d:mscd000 autoexec.bat中c:\dos\mscdex /d:mscd000 /l:g配置了一个光驱,符号为g参数/d rive1为光驱身份号,须与config.sys中的符号一致,可有多个/d:mscd000 /d:mscd001/e:使用扩展内存装入光驱驱动程序./s:使光驱在ms_net或windows是否设置为共享光驱/V是否在加载时显示内存./L:letter 分配给光驱的盘符/m:number 指定缓冲器的数目应该注意的是:?如果用smartdrv.exe 加速对光驱的读写能力,应该在autoexec. bat中将mscdex.?exe 写在smartdrv.exe 之前,smartdrv.exe的使用可大幅提高对驱动器的读写能力.二十、msd的使用使用msd 可以整体检查计算机配置及系统信息包括:?驱动器参数,计算机cpu参数,内存大小参数,显示器类型,串.并口情况,以及各个IRQ占用情况,据此可以分析新增设备是否与原来设备有冲突.同时也可以通过分析内存驻留程序,判断内存中是否有病毒,有那么标为"???".二十一、prompt dos提示符$q 等于号$t 当前时间$d 当前日期$p 当前驱动器符号$$ $号提示$n当前驱动器$g 大于号$l小于号$b 显示"|"管道号$h 隐去提示符$E显示"<-"号对于其它文字,那么直接显示文本本身prompt ljw,那么显示为ljw提示符prompt 那么仅显示当前驱动器号及大于号.二十二、ramdrive.sys 使用内存当做虚拟盘来使用应注意,所有数据都存在于内存中,应及时将其存到硬盘中,否那么掉电后或者死机后将丧失全部数据,优点是运行速度快,但不能在windows中使用.例如:config.sys: device=c:\dos\ramdrive.sys /size[/e|a]size为以k为单位的字节数,即建立的虚拟盘的大小./e或/a 都是使用扩展内存来建立虚拟盘,?加参数的前提是必须先加载内存管理器himem.sys及emm386.exe.二十三、subst 将一个驱动器与一个子目录联接如:将对A:\l1\l2 子目录的请求映射为S盘,那么输入subst s: a:\l1\l2 即可这样使用dir s:?等命令那么显示的是a:\l1\l2子目录下的内容,其它copy del 一样可以用subst s: d 来取消这种映射.可以用subst 来显示各种联接情况注意:?可以采用subst a: c:a 来建立一个对于A的读写盘.对于某些安装软件来说,?必须使用A盘来安装,就可以使用先将所要安装的软件全部拷贝到C:a子目录中,然后输入subst a: c:a,再转到A:,就可以进行软件的安装了.二十四、mem /c /m /p /d 常规内存显示程序/c显示所有内存驻留程序的占用情况,分为conventional常规内存和uppermemory 高端内存占用,并显示总的占用情况(常规高端保存扩展内存)/p分页显示,页间暂停/m后加模块名如:/m msdos 显示dos系统内存的占用./d对常规高端保存扩展内存加以详细例表说明通过分析,可以看出内存占用是否合理,以及各种程序是否正常加载,从而在此基础上使用内存优化工具memmaker进行各种管理,同时又可以分析出一些程序死机的原因,假设有的地方显示"???",那么可以断定内存中有病毒的存在,有利于发现及消灭.二十五、各种管道工具的使用"> < >> <<"将各种命令造成的输出或所需要的输入重新定向如ir *.bat /b>p 可以将dir *.bat 例出的文件名输出到p文件中.time<p>>p.batp文件中仅存在一个回车符,那么可以将时间追加进p.bat文件中"> >>" 是将命令产生的输出重新定向,比方到文件或打印机中.>>产生的内容将追加进文件中,>那么将原文件内容覆盖."< <<" 是将命令所需要输入的内容重新定向.如:time<p 在批中可以是时间代码或回车符,可以以此改变时间.需要说明的是"prn "为打印机, "null"为空设备con 为显示器type p.bat>prn 可将p.bat打印出来.copy null p 可将p文件删除掉copy con p 可以在屏幕上编辑p文件,F6可以存盘退出type p>pp 完成p文件到pp 的复制type p|more 可在屏满时暂停显示二十六、move 命令move [y/-y] filename1 filename2将文件1移动到文件2处如:move c:\dos\*.* c:\cced将dos子目录下的所有文件全部移动到cced 子目录下/y|-y参数在目标目录不存在需要创立时,是否出现提示可以使用该命令修改子目录名称,如move dos cced将dos目录名改为cced二十七、append 指定一些特殊数据文件的存放位置,如user.dat pe2.pro等一些非*. exe * *.bat 文件格式:append [:]终止以前存在的指定目录append 显示指定情况append [path] append c:\user 等二十八、call 在一个批处理命令中调用另外一个批处理文件(1)不终止现有文件的运行,执行完掉用程序后立即返回.(2)被调用批处理命令必须以bat 为扩展名(3)调用批处理文件时,可以加上参数(%1-%9)以及环境变量如%baud%(4)不能使用管道工具及重定向工具二十九、device devicehigh loadhighdevice 将指定的设备驱动程序装入内存中devicehigh将指定的设备驱动程序装入高端内存中loadhigh 将指定的设备驱动程序装入高端内存中三十、defrag 优化磁盘legend(传奇) optimize(优化) elapse(逝去) fragment(碎片)该命令执行对指定的盘进行优化处理(包括检查文件分配表,各文件状态,纠正错误), 在执行时,可按照文件名大小,时间,扩展名对文件进行排序.。
引导分区
谢谢观看
引导分区
计算机领域术语
01 主要区别
03 相关内容
目录ห้องสมุดไป่ตู้
02 扇区结构
硬盘主引导扇区是一个敏感的区域,它的安全与否直接决定硬盘是否能够正常使用。深入认识和灵活使用硬 盘主引导扇区将有助于你的系统维护和许多特殊工作完成。
主要区别
与DOS引导扇区的区别 对于DOS系统来说,有两种不同的引导扇区,即DOS引导扇区和硬盘主引导扇区。 DOS引导扇区存在于软盘的第 一逻辑扇区或硬盘DOS分区的第一逻辑扇区,是用FORMAT命令对磁盘格式化时产生的,是引导DOS系统或正确使用磁 盘的必要条件,在DOS下可用DEBUG方便地读出: C>DEBUG -L 100 2 0 1 ;读C盘0扇区到内存当前段的100H处 -D ;显示DOS引导扇区内容 硬盘主引导扇区则指的是硬盘的物理地址0面0道1扇区,是用FDISK进行硬盘分区时产生的,它属于整个硬盘而 不属于某个独立的DOS分区,是硬盘正确引导和使用的必要条件。由于它不在DOS分区范围之内,所以无法用上述方 法读出,只有用相关的汇编程序代码读出: C>DEBUG
扇区结构
硬盘主引导扇区占据一个扇区,共512(200H)个字节,具体结构如下: 1.硬盘主引导程序,位于该扇区的0-1BDH处; 2.硬盘分区表,位于1BEH-1FDH处,每个分区表占用16个字节,共4个分区表,16个字节各字节意义如下: 0:自举标志,80H为可引导分区,00为不可引导分区; 1~3:本分区在硬盘上的开始物理地址; 4:分区类型,其中1表示为12位FAT表的基本DOS分区;4为16位FAT表的基本DOS分区;5为扩展DOS分区;6为 大于32M的DOS分区;其它为非DOS分区。 5~7:本分区的结束地址; 8~11:该分区之前的扇区数,即此分区第一扇区的绝对扇区号; 12~15:该分区占用的总扇区数。 3.引导扇区的有效标志,位于1FEH-1FFH处,固定值为AA55H。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
DOS引导扇区代码详解如果从软盘起动,则Dos引导程序被ROM BIOS直接加载到内存,若从硬盘起动,则被硬盘的主引导程序加载.不过都是被加载到内存的绝对地址0000:7C00H处.因此,Dos引导程序的第一条指令的地址一定是0000:7C00H.[本人注:本文所述的dos引导代码已经在bootsect.bak, 可以用winhex打开参考,但我试用过得,似乎有点问题,直接就到最后的—“Non-sytem disk or disk error... Replace and press any key when ready”]Dos引导程序所做的事情如下:1>调整堆栈位置2>修改并用修改后的磁盘参数表来复位磁盘系统3>计算根目录表的首扇区的位置及IO.SYS的扇区位置4>读入根目录表的首扇区5>检查根目录表的开头两项是否为IO.SYS及MSDOS.SYS6>将IO.SYS文件开头三个扇区读入内存0000:0700H处7>跳到0000:0700H处执行IO.SYS,引导完毕上述每一步若出错,则显示"Non system disk or disk error..."信息,等用户按任一键后试图重新起动.下面的Dos引导程序是从硬盘上得来的,显示MSDOS5.0,但Dos的ver命令报告的是6.22版.FAT表自然是16位的.说明:(DX) 表示寄存器DX的值逻辑扇区号以0面0道1扇区作为逻辑0扇区,而不是以Dos引导扇区为逻辑0扇区,当然,对软盘来说二者是相同的,对硬盘则不同面号即磁头号磁道号即柱面号(对硬盘)物理扇区号由面号,磁道号,扇区号三者共同指定偏移机器码符号指令说明==============================================================================0000 EB3C JMP 003E ;跳过数据区;以下数据是厂商OEM信息和磁盘BPB表0000 90 4D 53 44 4F 53-35 2E 30 00 02 08 01 00 .MSDOS5.0.....0010 02 00 02 00 00 F8 CC 00-3F 00 10 00 3F 00 00 00 ........?...?...0020 F1 59 06 00 80 00 29 E3-0B 3F 26 53 4C 4D 20 20 .Y....)..?&SLM0030 20 20 20 20 20 20 46 41-54 31 36 20 20 20 FAT16------------------------------------------------------------------------------003E FA CLI003F 33C0 XOR AX,AX0041 8ED0 MOV SS,AX0041 8ED0 MOV SS,AX0043 BC007C MOV SP,7C00 ; 初始化堆栈0046 16 PUSH SS0047 07 POP ES ;(ES)=0000H0048 BB7800 MOV BX,0078 ;1EH 号中断向量的地址为0000:0078H004B 36 SS: ;(SS)=0000H004C C537 LDS SI,[BX] ;取1EH号中断向量的内容存入DS:SI004E 1E PUSH DS ;该中断向量指向一个11字节的磁盘参;数表004F 56 PUSH SI ;取到后压入堆栈中保存0050 16 PUSH SS0051 53 PUSH BX ;保存地址0000:0078H 0052 BF3E7C MOV DI,7C3E ;7C3E-7C00=003EH,即偏移003EH,以下;类推0055 B90B00 MOV CX,000B ;磁盘参数表共11字节0058 FC CLD0059 F3 REPZ005A A4 MOVSB ;将磁盘参数表复制到0000:7C3EH处005B 06 PUSH ES005C 1F POP DS ;(DS)=0000H005D C645FE0F MOV BYTE PTR [DI-02],0F ;修改参数表中"磁头定位时间"0061 8B0E187C MOV CX,[7C18] ;从BPB中取"每磁道扇区数"0065 884DF9 MOV [DI-07],CL ;修改参数表中"每磁道扇区数"0068 894702 MOV [BX+02],AX ;(AX)=0000H,修改1EH号中断向量;(段址) 006B C7073E7C MOV WORD PTR [BX],7C3E ;修改1EH号中断向量(偏移),这;样1EH号006F FB STI ;中断向量的内容为0000:7C3EH,指向新的磁盘参;数表0070 CD13 INT 13 ;用新的磁盘参数表来复位磁盘0072 7279 JB 00ED ;出错则转出错处理-------------------------------------------------------------------------------; 下面一段程序计算扇区位置0074 33C0 XOR AX,AX0076 3906137C CMP [7C13],AX ;偏移0013H处是Dos分区的总扇区数007A 7408 JZ 0084 ;为零表示大硬盘?007C 8B0E137C MOV CX,[7C13] ;不为0则取出来放到偏移0020H处0080 890E207C MOV [7C20],CX ;这个值本程序未用,似乎为IO.SYS准备;的0084 A0107C MOV AL,[7C10] ;取FAT表的个数0087 F726167C MUL WORD PTR [7C16] ;乘以一个FAT表所占的扇区数008B 03061C7C ADD AX,[7C1C] ;加上Dos分区前的扇区数(隐藏扇数,低位)008F13161E7C ADC DX,[7C1E] ;高位)0093 03060E7C ADD AX,[7C0E] ;加上Dos分区内的保留扇区数(低位) 009783D200 ADC DX,+00 ;(高位)009A A3507C MOV [7C50],AX ;根目录表的首扇的逻辑扇区号(低位)009D8916527C MOV [7C52],DX ;(高位)00A1 A3497C MOV [7C49],AX ;此处放IO.SYS的首扇的逻辑扇区号(低;位) 00A489164B7C MOV [7C4B],DX ;(高;位) 00A8 B82000 MOV AX,0020 ;根目录表中每项占32字节00AB F726117C MUL WORD PTR [7C11] ;乘以根目录表中的项数00AF 8B1E0B7C MOV BX,[7C0B] ;取"每扇区的字节数"00B3 03C3 ADD AX,BX ;这两条指令是为了取整00B5 48 DEC AX00B6 F7F3 DIV BX ;除以每扇字节数,得到根目录所占扇区;数00B8 0106497C ADD [7C49],AX ;得到根目录表后首扇的逻辑扇区号(低;位) 00BC 83164B7C00 ADC WORD PTR[7C4B],+00 ; (高;位)-------------------------------------------------------------------------------;下面一段程序在根目录表中找系统文件IO.SYS和MSDOS.SYS00C1 BB0005 MOV BX,0500 ;内存缓冲区的偏移值00C4 8B16527C MOV DX,[7C52] ;取根目录表的首扇的逻辑扇区号(高;位) 00C8A1507C MOV AX,[7C50] ;(低;位) 00CB E89200 CALL 0160 ;将逻辑扇区号转换为物理扇区号00CE 721D JB 00ED ;出错则转出错处理00D0 B001 MOV AL,0100D2 E8AC00 CALL 0181 ;读一个扇区到内存(根目录的首扇)00D5 7216 JB 00ED ;出错处理00D7 8BFB MOV DI,BX ;内存缓冲区的首址00D9 B90B00 MOV CX,000B ;比较11个字节00DC BEE67D MOV SI,7DE6 ;偏移01E6处是串"IO SYS",长11;字节00DF F3 REPZ00E0 A6 CMPSB ;看第一项是否为IO.SYS00E1 750A JNZ 00ED ;不是则出错00E3 8D7F20 LEA DI,[BX+20] ;跳过32字节就指向第二项00E6 B90B00 MOV CX,000B ;比较11个字节00E9 F3 REPZ00EA A6 CMPSB ;看第二项是否为MSDOS.SYS00EB 7418 JZ 0105 ;是则两个文件都已找到,跳过出错处理------------------------------------------------------------------------------;下面一段进行出错处理00ED BE9E7D MOV SI,7D9E ;偏移019EH处是串"Non system disk.;.." 00F0 E85F00 CALL 0152 ;显示字符串00F3 33C0 XOR AX,AX00F5 CD16 INT 16 ;等待任一键按下00F7 5E POP SI00F8 1F POP DS ;得到1EH号中断向量的地址0000:0078H00F9 8F04 POP [SI]00FB 8F4402 POP [SI+02] ;恢复1EH号中断向量的内容00FE CD19 INT 19 ;自举0100 58 POP AX0101 58 POP AX0102 58 POP AX ;清理堆栈0103 EBE8 JMP 00ED ;再次试图起动------------------------------------------------------------------------------;下面读入IO.SYS的头3个扇区到内存0000:0700H处0105 8B471A MOV AX,[BX+1A] ;从根目录表第一项中取IO.SYS的首簇;号0108 48 DEC AX0109 48 DEC AX ;首簇号减二010A 8A1E0D7C MOV BL,[7C0D] ;取每簇的扇区数010E 32FF XOR BH,BH0110 F7E3 MUL BX ;(首簇号 - 2)乘以每簇的扇区数0112 0306497C ADD AX,[7C49] ;相加后得到IO.SYS的首扇的逻辑扇区;号0116 13164B7C ADC DX,[7C4B]011A BB0007 MOV BX,0700 ;内存缓冲区的偏移值011D B90300 MOV CX,0003 ;循环计数初值,读3个扇区0120 50 PUSH AX ;逻辑扇区号进栈(低位) 012152 PUSH DX ;(高位)0122 51 PUSH CX ;循环计数器进栈0123 E83A00 CALL 0160 ;逻辑扇区号转换为物理扇区号0126 72D8 JB 0100 ;出错处理0128 B001 MOV AL,01012A E85400 CALL 0181 ;读一个扇区到内存缓冲区012D 59 POP CX ;循环计数出栈012E 5A POP DX012F 58 POP AX ;逻辑扇区号出栈0130 72BB JB 00ED ;读盘出错处理0132 050100 ADD AX,00010135 83D200 ADC DX,+00 ;下一个扇区0138 031E0B7C ADD BX,[7C0B] ;缓冲区指针移动一个扇区的大小013C E2E2 LOOP 0120 ;循环读入三个扇区013E 8A2E157C MOV CH,[7C15] ;取"磁盘介质描述",传给IO.SYS 0142 8A16247C MOV DL,[7C24] ;取"系统文件所在的驱动器号"0146 8B1E497C MOV BX,[7C49] ;取IO.SYS的首扇的逻辑扇区号014A A14B7C MOV AX,[7C4B]014D EA00007000 JMP 0070:0000 ;执行IO.SYS,引导完毕------------------------------------------------------------------------------;显示字符串的子程序0152 AC LODSB ;从串中取一个字符0153 0AC0 OR AL,AL0155 7429 JZ 0180 ;为0则已到串尾,返回(共用RET指令)0157 B40E MOV AH,0E0159 BB0700 MOV BX,0007015C CD10 INT 10 ;显示该字符015E EBF2 JMP 0152 ;循环显示下一个----------------------------------------------------------------------------;将逻辑扇区号转换为物理扇区号的子;程序0160 3B16187C CMP DX,[7C18] ;这两条指令是为了避免第二次除法时;除数0164 7319 JNB 017F ;为00166 F736187C DIV WORD PTR [7C18] ;逻辑扇取号除以每道扇区数,商(AX)=;总磁016A FEC2 INC DL ;道数,余数(DX)再加一即为扇区号,因;为扇016C 88164F7C MOV [7C4F],DL ;区号是从1开始的,而不是从0开始0170 33D2 XOR DX,DX0172 F7361A7C DIV WORD PTR [7C1A] ;总磁道数(AX)再除以面数,所得的0176 8816257C MOV [7C25],DL ;余数(DX)=面号(即磁头号)017A A34D7C MOV [7C4D],AX ;商(AX)=磁道号017D F8 CLC017E C3 RET ;正常返回017F F9 STC0180 C3 RET ;异常返回---------------------------------------------------------------------;读一个扇区的子程序0181 B402 MOV AH,02 ;读功能调用0183 8B164D7C MOV DX,[7C4D] ;需要的入口参数如下:0187 B106 MOV CL,06 ;(DL)=驱动器号0189 D2E6 SHL DH,CL ;(DH)=面号018B 0A364F7C OR DH,[7C4F] ;(CH)=磁道号。