- UID
- 4308
- UCC
-
- 声望
-
- 好评
-
- 贡献
-
- 最后登录
- 1970-1-1
|
我们经常遇到各种各样的硬盘故障,其中有相当部分是硬盘软故障,如有些朋友在安装Linux后,发现无法安装Windows等,但很多朋友由于在对硬盘的逻辑结构不是很了解,无法判断合解决该类问题。
为了普及这些知识,增强大家的兴趣和做试验成功后的成就感,本人以提问的形式给大家展现这方面的知识,同时也提醒大家在实做时先用一个多余而且无重要数据的硬盘做试验,免得造成不必要的损失。另外,对于汇编不了解但有一定计算机基础的朋友,建议自己查找资料进一步学习,也可以记下本文中的代码,实做中灵活应用。
问题:我们在安装所有版本的Windows时,一般不管使用Win 9X的Fdisk命令对硬盘进行分区,还是由安装程序进行分区,基本上都只能分一个主分区和一个扩展分区,扩展分区里面又分若干逻辑分区,很少人尝试过分多个主分区或多个扩展分区,今天有空出下面问题,随便做了个试验(Linux下做直接读Linux分区的文件试验导致硬盘Linux彻底被破坏,干脆。。。),结果如下:10G硬盘分为了3个主分区,而且还可以从任何一个主分区启动,也就是说,3个主分区装了3个操作系统。
问题:
(1)在只有基本的DOS情况下是如何做到的?(除了DOS,不允许用其它任何软件)
(2)一块硬盘最多可分为几个主分区和几个扩展分区?
目的:通过讨论,让大家
(1)深刻理解硬盘0面0道1扇区的MBR+DPT+BRI结构;
(2)掌握手动修改MBR和DPT的手段,具备手动备份和还原硬盘0面0道1扇区的能力;
(3)了解计算机从硬盘启动的过程,了解编写多重启动程序的基本方法;
(4)为将来学习其它操作系统打下良好的基础。
答案:(由于编辑窗口太小,可能有不少错误,也已修改不少,剩下的请指出)
关键词:
MBS- Master Boot Sector 主引导扇区
MBR-Master Boot Record 主引导记录
DPT-Disk Partition Table 硬盘分区表
BRI-Boot Record ID 引导记录标志
CHS-(Cylinder柱面,也就是磁道 编号0-m /Head 头,编号0-n /Sector 扇区 编号1-t)参数。
一、 硬盘结构和逻辑编号
(1)硬盘物理结构
传统硬盘由多个双面磁碟组成,每个面都有一个读写磁头,磁头编号从0开始,所谓0面就是指0磁头所对应的面;每个面被划为若干磁道,编号从负数开始,磁道数越小,越靠近磁碟边缘,因为线速度越大,所以读写速度也越快;用户只能使用0道以后的磁道,负磁道为硬盘所带的微处理器使用的一些代码(Fireware)和本硬盘一些重要参数存放的地方;每个磁道又分为若干扇区(每个磁道扇区数量都一样),扇区的编号从1开始(不是从0开始哟!),每个扇区存放536(这个数记不清楚了,呵呵)多个字节,但共用户使用的只有512个字节,剩下的作为校验(CRC)和其它用途。这就是著名的硬盘寻址CHS(Cylinder柱面,也就是磁道 编号0-m /Head 头,编号0-n /Sector 扇区 编号1-t)参数。
对于CHS中参数中
Cylinder柱,也就是磁道,用10个二进制数表示,所以最大为1024
Head 头,用一个字节表示,最大为256个磁头
Sector 扇区,用6为二进制数表示,所以最大为 64-1(不能用0呀)=63
所以使用CHS表示的硬盘最大容量为
1024X256X63X512=8455716864字节=8064M容量,这就是8G容量的由来。
明显看出,外道比内道长,被划分为同样扇区数是非常浪费的。现代磁盘基本上也只有2个左右的磁碟,4个面左右,每个磁道上的扇区数量都不相同,一般使用LBA表示方法来表示每个扇区,所谓LBA指每个扇区都有一个编号,从0开始(负编号不给用户使用),为了与CHS方式兼容,硬盘内部代码使用了一种CHS-LBA映射的方式。
(2)硬盘逻辑编号
当一台计算机挂多个IDE硬盘时,Linux/Unix对硬盘的编号最为科学。它是这样处理的
hda—第一个IDE口主硬盘,
hdb—第一个IDE口从硬盘,
hdc—第二个IDE口主硬盘,
hdd—第二个IDE口从硬盘,
但对于BIOS,DOS和Windows,处理方式有点不一样,只要掌握下面原则就可以了
(1) 上面4硬盘是连续编号,从小到大,光驱不算
(2) 作为启动的硬盘编号最小,为0x80(16进制数)
如第一个IDE口,主挂硬盘,从挂光驱,第二个ide口挂2个硬盘,BIOS设置从第二个主硬盘启动,则它们的编号为:
第二个IDE主硬盘为0x80,第一个IDE主硬盘为0x81,第二个IDE从硬盘为0x82
又如第一个IDE口主空,从挂硬盘,第二个IDE口主挂光驱,从挂硬盘,BIOS设置从第一个从硬盘启动,则它们的编号为:
第一个IDE从硬盘为0x80,第二个IDE从硬盘为0x81
二、 硬盘分区规范和制作多重启动程序的方法
所谓对硬盘分区,直观意义上理解,是逻辑上把硬盘分为几个块。本来就象西瓜一样,你爱怎么切就怎么切,如在CHS参数方式下,你完全可以把0面全部扇区当成一个区。为了能保证各个操作系统的一致,所以制定了一个硬盘分区规范,如果你不按这个规范做,硬盘肯定只能被你自己开发的操作系统使用。
这个规范规定:
(1) CHS参数中0面0道1扇区为硬盘分区信息和引导代码扇区(Master Boot Sector MBS),也就是LBA=0的扇区;
(2) 分区是按空心圆柱形(蛋卷形状)划分,如图所示
由于0面0道1扇区(MBS)保存启动代码和硬盘分区信息,如果这个扇区物理损坏,这个硬盘也就无法进行分区,导致硬盘无法使用。但是对于现代硬盘,由于它内部使用的是映射机制,完全可以把个好的扇区映射过来,修复硬盘。很多硬盘修复软件可以做到这点,比较有名的是MHDD和PC3000
对于这个重要扇区(512个字节)的规范为:
MBR—Master Boot Record,主引导记录,共446个字节。规范并没有规定代码是什么,很多软件公司都有自己的MBR,如MS的MBR,Linux的Grub或Lilo,DM的等。我们常用的DOS下的Fdisk /mbr其实就是使用MS的MBR覆盖这446个字节,Fdisk程序内部本身包含这段代码,有兴趣可以把Fdisk.EXE改名为Fdisk.Txt,再用记事本打开,可以看到如下信息Invalid partition table.Error loading operating system.Missing operating system。
MS的这段代码的功能是查找引导分区信息或者叫活动分区(在MBR后面),如果没有或为2个以上,则显示以上信息,系统引导失败;否则再按引导分区项读对应引导扇区,判断结尾是否为55AA,是的话把CPU的控制权交给引导扇区对应的代码;否则引导失败。
当然我们也可以编写自己的MBR,做多重启动,这个大家先反汇编MS的MBR,认真研究以后就不难了,呵呵。
对于这个MBR,MS非常霸道,如果你安装了Linux的Grub,你就别想在这个硬盘上安装Windows,这个问题在TPY BBS里面出现过多次(本人也回答过多次,对于一些人动不动就叫别人对硬盘低级格式化的做法有点反感),最快的解决方法是:Fdisk /mbr,当然如果你的硬盘东西都不要的话,可以往MBS里面写一堆垃圾,破坏后面要说的BRI,让Windows安装程序认为MBS非法,然后在安装程序里面重新分区就可以了
DPT—Disk Partition Table 硬盘分区表,这是硬盘最重要的信息,这种信息被破坏,也就不知道硬盘是怎么分区的了,不过现在有些软件通过搜索可以找回分区信息,如easyrecovery.
DPT共64个字节,分为4项,每项16个字节对应一个分区。
分区规范规定:一个硬盘可以有多个主分区(Primary Partition),但最多只能有一个扩展分区(Extended Partition),一个扩展分区可以划分为多个逻辑分区,所以一个硬盘最多只能划为4个主分区或者3个主分区+一个扩展分区。
MS真懒,它的OS最多只让我们划一个主分区+一个扩展分区,其它OS没这个问题。
每个分区项的结构如下:
偏移 内容 大小
00h 0x80表示活动分区,00不活动 1BYTE,由于这个字节为MBR代码所识别,我们完全可以编写自己的MBR,不理会该字节内容,启动时选择所要启动的分区。甚至设置全部的分区为活动分区都可以。无论为怎么样填写,作为从盘,都能被操作系统所识别
01h 分区开始磁头编号(面号) 1BYTE
02h低6位 分区开始扇区号 6位二进制数
02h高2位和03h 分区开始的柱面数,也叫道编号 10位二进制数
04h 分区类型 1Byte,标识这个分区的类型,如果我们把这个直接内容修改了,会使得操作系统不能认出这个分区,间接保护了这个分区的资料,当然我们也可以往MBS写一堆垃圾来保护整个硬盘资料,当我们自己要用时,就恢复MBS
05h 分区结束磁头编号 1Byte
06h 分区结束的柱面和扇区,结构同上 2byte
08h 该分区第一扇区到MBS的总扇区数量 4Byte
0Ch 该分区的总扇区数量 4Byte
分区类型:
00h 未知类型或不用
01h 12bit Fat
04h 16bit fat
05h 扩展MS_DOS分区
0Bh Fat32 容量最大2G
0Ch Fat32 ,采用LBA模式,调用int13h扩展中断
0Fh 扩展MS_DOS分区,Fat32 ,采用LBA模式,调用int13h扩展中断
07h NTFS
82h Linux
83h Linux Swap
BRI――Boot Record ID 引导记录标志 接在DPT后面的最后2个字节为 55 AA,表示这个扇区是个正常的计算机启动时,BIOS把这个扇区读入内存,发现BRI不是55 AA,则会拒绝启动。
如下面一个MBS内容
0FA2:0200 33 C0 8E D0 BC 00 7C FB-50 07 50 1F FC BE 1B 7C 3.....|.P.P....|
0FA2:0210 BF 1B 06 50 57 B9 E5 01-F3 A4 CB BE BE 07 B1 04 ...PW...........
0FA2:0220 38 2C 7C 09 75 15 83 C6-10 E2 F5 CD 18 8B 14 8B 8,|.u...........
0FA2:0230 EE 83 C6 10 49 74 16 38-2C 74 F6 BE 10 07 4E AC ....It.8,t....N.
0FA2:0240 3C 00 74 FA BB 07 00 B4-0E CD 10 EB F2 89 46 25 <.t...........F%
0FA2:0250 96 8A 46 04 B4 06 3C 0E-74 11 B4 0B 3C 0C 74 05 ..F...<.t...<.t.
0FA2:0260 3A C4 75 2B 40 C6 46 25-06 75 24 BB AA 55 50 B4 :[email protected]%.u$..UP.
0FA2:0270 41 CD 13 58 72 16 81 FB-55 AA 75 10 F6 C1 01 74 A..Xr...U.u....t
0FA2:0280 0B 8A E0 88 56 24 C7 06-A1 06 EB 1E 88 66 04 BF ....V$.......f..
0FA2:0290 0A 00 B8 01 02 8B DC 33-C9 83 FF 05 7F 03 8B 4E .......3.......N
0FA2:02A0 25 03 4E 02 CD 13 72 29-BE 46 07 81 3E FE 7D 55 %.N...r).F..>.}U
0FA2:02B0 AA 74 5A 83 EF 05 7F DA-85 F6 75 83 BE 27 07 EB .tZ.......u..'..
0FA2:02C0 8A 98 91 52 99 03 46 08-13 56 0A E8 12 00 5A EB ...R..F..V....Z.
0FA2:02D0 D5 4F 74 E4 33 C0 CD 13-EB B8 00 00 80 58 30 17 .Ot.3........X0.
0FA2:02E0 56 33 F6 56 56 52 50 06-53 51 BE 10 00 56 8B F4 V3.VVRP.SQ...V..
0FA2:02F0 50 52 B8 00 42 8A 56 24-CD 13 5A 58 8D 64 10 72 PR..B.V$..ZX.d.r
0FA2:0300 0A 40 75 01 42 80 C7 02-E2 F7 F8 5E C3 EB 74 49 [email protected]......^..tI
0FA2:0310 6E 76 61 6C 69 64 20 70-61 72 74 69 74 69 6F 6E nvalid partition
0FA2:0320 20 74 61 62 6C 65 00 45-72 72 6F 72 20 6C 6F 61 table.Error loa
0FA2:0330 64 69 6E 67 20 6F 70 65-72 61 74 69 6E 67 20 73 ding operating s
0FA2:0340 79 73 74 65 6D 00 4D 69-73 73 69 6E 67 20 6F 70 ystem.Missing op
0FA2:0350 65 72 61 74 69 6E 67 20-73 79 73 74 65 6D 00 00 erating system..
0FA2:0360 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA2:0370 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA2:0380 00 00 00 8B FC 1E 57 8B-F5 CB 00 00 00 00 00 00 ......W.........
0FA2:0390 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA2:03A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA2:03B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00
以上是MBR
80 01 ................
0FA2:03C0 01 00 0B FE 7F 7E 3F 00-00 00 80 E2 5D 00 00 00 .....~?.....]...
0FA2:03D0 41 7F 05 FE FF 0F BF E2-5D 00 51 4C 62 00 00 00 A.......].QLb...
0FA2:03E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA2:03F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00
以上是DPT
55 AA ..............U.
最后这个是BRI了,呵呵
共2个分区,一个主分区(分区类型为0B)+一个扩展分区(分区类型为05)
第一个分区信息
80 01 01 00 0B FE 7F 7E 3F 00-00 00 80 E2 5D 00
80-这是一个活动分区
01-分区起始磁头号为1,也就是0头0道除了MBS使用一个扇区以外其它没有使用,我们可以在那里保存MBS内容(备份呀),也可以放代码,因为446个字节也许不够我们用,呵呵
01 00 =0000001 00000000,分区开始扇区数为000001=1,开始磁道数为0000000000=0
0B-- Fat32主分区
FE--分区结束磁头数FE= 254,可以看出在CHS模式下,该硬盘有255个磁头
7F 7E=0111 1111 0111 1110,分区结束扇区数11 1111(b)=63
分区结束磁道数01 0111 1110=382
3F 00-00 00-分区前面的扇区数为0000003F=63,刚好是0道所占的扇区数
80 E2 5D 00-分区的总扇区数为005DE280=6152832, 6152832X512/(1024X1024)= 3004.3125M=3G,完全正确!
三、 使用BIOS直接对硬盘操作方法
(1) BIOS中断int 13
BIOS已经为我们准备了读写磁盘的代码,这就是Int 13(13h号中断),但很多操作系统在启动完成后都不使用这些代码,而使用扩展的LBA访问模式(驱动程序所带的代码),以突破8G容量的限制和实现DMA访问模式。另外在Winnt以上版本OS,由于MBS是重要的信息区,系统禁止用户对MBS进行读写操作,全部的防病毒软件也对该扇区进行了保护。
所以只有DOS和Win 9X才能使用int 13h访问MBS
调用int 13h的入口参数为
ah=2 读磁盘 =3 写磁盘
入口参数:AH=功能号,02为读盘操作;03为写磁盘;AL=一次读取的扇区数
; ES:BX=读入内存的起始地址
; CH=10位柱面号的低8位;CL:高两位是10位柱面号的高两位,低6位是扇区号
; DH=磁头号;
DL=驱动器号,00代表第一个软驱;对于硬盘是硬盘编号,0x80为第一个硬盘,也就是系统启动的硬盘
(2) Debug使用方法
在DOS的DEBUG程序里面,我们可以编写简单的汇编程序,如使用A命令则是输入代码,使用U命令是反汇编,具体大家可以查找相应的教材,也可以使用?命令得到帮助,如
注在DEBUG里面,所有数据全部为16进制数
C:\WINDOWS>debug
-?(注:获取帮助)
assemble A [address]
compare C range address
dump D [range]
enter E address
fill F range list
go G [=address] [addresses]
hex H value1 value2
input I port
load L [address] [drive] [firstsector] [number]
move M range address
name N [pathname] [arglist]
output O port byte
proceed P [=address] [number]
quit Q
register R [register]
search S range list
trace T [=address] [value]
unassemble U [range]
write W [address] [drive] [firstsector] [number]
allocate expanded memory XA [#pages]
deallocate expanded memory XD [handle]
map expanded memory pages XM [Lpage] [Ppage] [handle]
display expanded memory status XS
-a100(注:从100开始汇编代码)
0FA2:0100 mov ax,201(注ah=2,读磁盘,al=1读一个扇区,如果是写一个扇区,就改为mov ax,301)
0FA2:0103 mov bx,200 (注内容放在200处)
0FA2:0106 mov cx,1 (注ch=0,cl=1,0面1扇区)
0FA2:0109 mov dx,80 (注dh=0,0道,dl=80 第一个硬盘,即启动硬盘)
0FA2:010C int 13 (注 执行磁盘操作代码)
0FA2:010E int 20 (注:程序结束)
0FA2:0110
-
-u100(注:反汇编)
0FA2:0100 B80102 MOV AX,0201
0FA2:0103 BB0002 MOV BX,0200
0FA2:0106 B90100 MOV CX,0001
0FA2:0109 BA8000 MOV DX,0080
0FA2:010C CD13 INT 13
0FA2:010E CD20 INT 20
0FA2:0110 0283470D ADD AL,[BP+DI+0D47]
0FA2:0114 02806F0A ADD AL,[BX+SI+0A6F]
0FA2:0118 2480 AND AL,80
0FA2:011A 47 INC DI
0FA2:011B 0A34 OR DH,[SI]
0FA2:011D 00910F83 ADD [BX+DI+830F],DL
-g(注:运行)
Program terminated normally
-d200 (显示读出来的结果,MBS)
0FA2:0200 33 C0 8E D0 BC 00 7C FB-50 07 50 1F FC BE 1B 7C 3.....|.P.P....|
0FA2:0210 BF 1B 06 50 57 B9 E5 01-F3 A4 CB BE BE 07 B1 04 ...PW...........
0FA2:0220 38 2C 7C 09 75 15 83 C6-10 E2 F5 CD 18 8B 14 8B 8,|.u...........
0FA2:0230 EE 83 C6 10 49 74 16 38-2C 74 F6 BE 10 07 4E AC ....It.8,t....N.
0FA2:0240 3C 00 74 FA BB 07 00 B4-0E CD 10 EB F2 89 46 25 <.t...........F%
0FA2:0250 96 8A 46 04 B4 06 3C 0E-74 11 B4 0B 3C 0C 74 05 ..F...<.t...<.t.
0FA2:0260 3A C4 75 2B 40 C6 46 25-06 75 24 BB AA 55 50 B4 :[email protected]%.u$..UP.
0FA2:0270 41 CD 13 58 72 16 81 FB-55 AA 75 10 F6 C1 01 74 A..Xr...U.u....t
-d
0FA2:0280 0B 8A E0 88 56 24 C7 06-A1 06 EB 1E 88 66 04 BF ....V$.......f..
0FA2:0290 0A 00 B8 01 02 8B DC 33-C9 83 FF 05 7F 03 8B 4E .......3.......N
0FA2:02A0 25 03 4E 02 CD 13 72 29-BE 46 07 81 3E FE 7D 55 %.N...r).F..>.}U
0FA2:02B0 AA 74 5A 83 EF 05 7F DA-85 F6 75 83 BE 27 07 EB .tZ.......u..'..
0FA2:02C0 8A 98 91 52 99 03 46 08-13 56 0A E8 12 00 5A EB ...R..F..V....Z.
0FA2:02D0 D5 4F 74 E4 33 C0 CD 13-EB B8 00 00 80 58 30 17 .Ot.3........X0.
0FA2:02E0 56 33 F6 56 56 52 50 06-53 51 BE 10 00 56 8B F4 V3.VVRP.SQ...V..
0FA2:02F0 50 52 B8 00 42 8A 56 24-CD 13 5A 58 8D 64 10 72 PR..B.V$..ZX.d.r
-d
0FA2:0300 0A 40 75 01 42 80 C7 02-E2 F7 F8 5E C3 EB 74 49 [email protected]......^..tI
0FA2:0310 6E 76 61 6C 69 64 20 70-61 72 74 69 74 69 6F 6E nvalid partition
0FA2:0320 20 74 61 62 6C 65 00 45-72 72 6F 72 20 6C 6F 61 table.Error loa
0FA2:0330 64 69 6E 67 20 6F 70 65-72 61 74 69 6E 67 20 73 ding operating s
0FA2:0340 79 73 74 65 6D 00 4D 69-73 73 69 6E 67 20 6F 70 ystem.Missing op
0FA2:0350 65 72 61 74 69 6E 67 20-73 79 73 74 65 6D 00 00 erating system..
0FA2:0360 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA2:0370 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
-d
0FA2:0380 00 00 00 8B FC 1E 57 8B-F5 CB 00 00 00 00 00 00 ......W.........
0FA2:0390 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA2:03A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA2:03B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 80 01 ................
0FA2:03C0 01 00 0B FE 7F 7E 3F 00-00 00 80 E2 5D 00 00 00 .....~?.....]...
0FA2:03D0 41 7F 05 FE FF 0F BF E2-5D 00 51 4C 62 00 00 00 A.......].QLb...
0FA2:03E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA2:03F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA ..............U.
若要备份MBS内容,只要在Debug里面读出来后
使用以下命令就可以了
-n E;\Boot.bin(放MBS的文件)
-rcx
200 (MBS的长度,16进制的0x200=十进制的512,一个扇区的字节数)
-w200 把200开始的地方按刚才的设置的512长度内容写入所设置的文件里面
若要恢复MBS内容,使用
-n E;\Boot.bin(放MBS的文件)
-l 200(读入以上文件内容到200位置)
然后再使用A命令编写与上面类似代码,将内容写入MBS
四、 本问题实做方法
通过对以上知识的了解,要达到本问题中将硬盘直接分为多个主分区的目的,其实最直接的方法是自己计算填写DPT+BRI,然后写入硬盘DBS,再用Fdisk /mbr将mbr写入DBS。然而,这种计算比较繁琐和容易出错,能否借Fdisk帮助我们自动计算呢?可以!
(1) 使用Fdisk先划一个主分区,再划一个扩展分区,无所谓里面建多少个逻辑分区,反正等下这个扩展分区要变为主分区。在划分时要留下空间给后面的主分区;
(2) 不要重新启动计算机,使用debug编写程序读出该硬盘的MBS内容,将分区表第二项的分区类型由原来的0X05(扩展分区类型)改为主分区类型0X0B或0X0C,再写回分区表
(3) 在另外一个DOS窗口里面运行Fdisk,可以看到有2个主分区了,再建立一个扩展分区,退出,不要重新启动
(4) 再到(2)中窗口重新读出MBS内容,把MBR第三项分区类型改为主分区,且写回MBS;
(5) 进入Fdisk,这次看到应该是3个主分区,把剩余空间分为一个扩展分区,建立若干逻辑分区,激活3个主分区中的一个。退出后重新启动计算机
(6) 最后对各分区进行格式化,因为第二和第三主分区在使用Fdisk时还建立了逻辑分区,导致格式化也许会出现错误,不用理会,Format会对该2个主分区进行完整的格式化。
五、最后在本人计算机上做了个MBR,让大家看看效果
本人计算机设置了2个主分区,前一个是Windows 98,另外一个是DOS 7.0,为保险期间,将原来的MBS备份到0面0道2扇区
MBR的源代码为:(Nasm编译,不是Masm,呵呵!看不懂?先看效果,再努力学习,回头再看!)
org 0h ;为了编译器准确定位,这里应该为绝对定位,BIOS把MBS内容读入0000:7c00h
section .text
mov ax,7c0h ;段地址设置
mov ds,ax
mov ax,9000h ;目标段地址
mov es,ax
mov cx,200h ;200h个字,即512个字节
sub si,si ;源07c0:0000即0000:7c00h
sub di,di ;目的9000h:0000
cld ;正向
repz movsw ;复制,把0000:7c00的512个Byte复制到9000h:0000,即MBS被复制到9000h:0000
jmp 9000h:go ;跳转到9000h的下条语句,因为使用绝对定位,所以go的偏移正确
go: mov ds,ax ;ax=es=9000h
mov ss,ax ;设置堆栈段
mov sp,ax
call cls ;清屏幕,设置光标到(0,0)
mov cx,tail-head ;cx=要显示的文字长度
mov bx,0eh ;字符颜色 0eh为黄色
mov bp,head ;字符串的首地址偏移
mov ax,1301h ;int 10h的显示功能
int 10h ;显示
redo:
mov ah,1 ;下面3句是清除键盘缓冲区内容
int 16h
jnz redo
sub ah,ah ;读键盘
int 16h ;返回:ah-ascii码,al-扫描码
sub al,31h ;与“1”的扫描码相减
jz next ;按的健确实是"1"
cmp al,1 ;原来扫描码是1+31=32?即按键是“2”?
jz next ;按键是"1"和“2”,到下一步al=0按了“1”,al=1按键为"2"
jmp redo ;不是按“1”或“2”
next:
sub ah,ah
shl al,4 ;al=al*16,因为一个分区表项为16个字节,上面2句得到要启动的分区的分区表项与分区表首地址的相对位移
mov si,ax
mov bp,1beh ;分区表首地址
cmp byte[bp+si],80h ;要启动分区的分区表第一个字节是否为活动分区?(因为DOS/Windows还会读分区表,所以必须修改分区表对应这个字节,对Linux则不需要)
jz read
mov byte[bp],0 ;
mov byte[bp+16],0 ;前2个先改为非活动分区
mov byte[bp+si],80h ;被启动的改为活动
mov ax,301h
xor bx,bx
mov cx,1
mov dx,80h
int 13h ;写回MBS到硬盘
read:
mov dx,[bp+si]
mov cx,[bp+si+2]
xor ax,ax
mov es,ax
mov bx,7c00h
mov ax,201h
int 13h ;以上是读被启动分区的第一个扇区(该分区的引导扇区)到0000:7c00h
call cls ;清屏幕,设置光标到(0,0)
jmp 0:7c00h ;远跳转到被启动分区的引导代码
cls:
mov ax,3
int 10h ;设置显示模式为3(16色80X25 VGA模式,同时清屏)
mov ah,02
sub dx,dx
sub bh,bh
int 10H ;设置光标位置为(0,0)
ret
head: db "Boot Loader. Made By Liao 2006.02.19",0dh,0ah
db "Partition 1:Microsoft Windows 98",0dh,0ah
db "Partition 2:Microsoft DOS 7.0",0dh,0ah
db "Choose the Boot Partition Number(1,2)"
tail:
MBS内容为:
D:\code>debug
-a
0FA5:0100 mov ax,201
0FA5:0103 mov bx,200
0FA5:0106 mov cx,1
0FA5:0109 mov dx,80
0FA5:010C int 13
0FA5:010E int 20
0FA5:0110
-g
Program terminated normally
-d200
0FA5:0200 B8 C0 07 8E D8 B8 00 09-8E C0 B9 00 02 29 F6 29 .............).)
0FA5:0210 FF FC F3 A5 EA 19 00 00-09 8C C8 8E D8 8E C0 8E ................
0FA5:0220 D0 BC 00 04 E8 70 00 B9-93 00 BB 07 00 BD A8 00 .....p..........
0FA5:0230 B8 01 13 CD 10 B4 01 CD-16 75 FA B4 00 CD 16 3C .........u.....<
0FA5:0240 31 75 06 BB BE 01 E9 07-00 3C 32 75 E8 BB CE 01 1u.......<2u....
0FA5:0250 80 3F 80 75 04 43 E9 22-00 53 BB BE 01 C6 07 00 .?.u.C.".S......
0FA5:0260 BB CE 01 C6 07 00 5B C6-07 80 43 53 B8 01 03 BB ......[...CS....
0FA5:0270 00 00 B9 01 00 BA 80 00-CD 13 5B B2 80 8A 37 43 ..........[...7C
-d
0FA5:0280 8B 0F B8 00 00 8E C0 BB-00 7C B8 01 02 CD 13 E8 .........|......
0FA5:0290 05 00 EA 00 7C 00 00 B8-03 00 CD 10 B4 02 BA 00 ....|...........
0FA5:02A0 00 B7 00 CD 10 C3 00 00-42 6F 6F 74 20 4C 6F 61 ........Boot Loa
0FA5:02B0 64 65 72 2E 20 4D 61 64-65 20 42 79 20 4C 69 61 der. Made By Lia
0FA5:02C0 6F 20 32 30 30 36 2E 30-32 2E 31 39 0D 0A 50 61 o 2006.02.19..Pa
0FA5:02D0 72 74 69 74 69 6F 6E 20-49 20 3A 4D 69 63 72 6F rtition I :Micro
0FA5:02E0 73 6F 66 74 20 57 69 6E-64 6F 77 73 20 39 38 0D soft Windows 98.
0FA5:02F0 0A 50 61 72 74 69 74 69-6F 6E 20 49 49 3A 4D 69 .Partition II:Mi
-d
0FA5:0300 63 72 6F 73 6F 66 74 20-44 4F 53 20 37 2E 30 0D crosoft DOS 7.0.
0FA5:0310 0A 43 68 6F 6F 73 65 20-57 68 69 63 68 20 50 61 .Choose Which Pa
0FA5:0320 72 74 69 74 69 6F 6E 20-59 6F 75 20 57 61 6E 74 rtition You Want
0FA5:0330 20 42 6F 6F 74 3F 28 31-2C 32 29 00 00 00 00 00 Boot?(1,2).....
0FA5:0340 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA5:0350 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA5:0360 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA5:0370 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
-d
0FA5:0380 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA5:0390 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA5:03A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA5:03B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 80 01 ................
0FA5:03C0 01 00 0B FE 7F 7E 3F 00-00 00 80 E2 5D 00
第一个主分区
00 00 .....~?.....]...
0FA5:03D0 41 7F 0C FE FF 0F BF E2-5D 00 51 4C 62 00
第二个主分区
00 00 A.......].QLb...
0FA5:03E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0FA5:03F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA ..............U.
:D
|
|