Web Presentation
and Text are Copyright © 2000-2007 by Daniel B. Sedory
(NOT to be reproduced in any form without Permission of
the Author !)
Introduction
This page examines the Windows OS Boot Record code for Windows 95B (OSR2), Windows 98, Windows 98SE and Windows ME (Millennium Edition) all of which use a 32-bit FAT for storing files on hard drives. There are differences in the SYS.COM programs for each of these versions, but if you compare, for example, Windows 95B's SYS.COM file (18,967 bytes 08-24-96 11:11am) with that of Windows 98's (18,967 bytes 05-06-98 8:01pm), you'll find that the differences are only in the Boot Record for floppy diskettes (FAT12), not hard disks (FAT32). [ For a detailed byte-by-byte comparison of the differences, see: SYSDIFFS.txt ]
The Boot Record itself:
Microsoft's MSWIN4.1 Boot Record is actually
3 sectors long, and is found at Logical Sectors 0
through 2 for any volume, or Absolute Sectors 63 through 65 of
a drive having only a single FAT32 partition, or when that partition is the
very first one on your Drive. It may obviously reside elsewhere if your HDD
is partitioned for multi-OS use. (Note: There's also a "Backup
Copy" of the MSWIN4.1 Boot Record which resides at Logical
Sectors 6 through 8 for any volume; which would be Absolute Sectors
69 through 71, in the case of the first or only FAT32 partition on
a drive.)
How the MSWIN4.1 Boot Record
appears in a Disk Editor is another page I wrote not only for those
who use disk editors, but to give you a general idea of the 'layout' of the
Boot Record. [ The link opens a new window, so you can refer to it later!
] The page includes color-highlighting
of the code, BPB, error messages, etc.
The MBR loads the MSWIN 4.1 Boot Record's first sector into the usual Memory location of 0000:7C00 and following. Locations 7C0Bh through 7C59h are filled by the BPB (BIOS Parameter Block), and the next 292 bytes (7C5A through 7D7D) contain this sector's executable code (the main program and various subroutines) which will in turn load the code from the third sector of the Boot Record. That last 512-byte sector contains most of the code which enables the Boot Record to read 32-bit FAT entries on the HDD so DOS (or Windows) can load parts of IO.SYS into Memory (which eventually enables the computer to load the rest of the OS). [Note: Unlike all previous Boot Records, the code in this one actually makes use of a useless byte (a 90h; NOP instruction) located in Memory (at 0000:7C02h) as a flag indicating whether or not Extended Interrupt 13 Disk Reads (Function 42h) are in use.]
See the Free Tools section below for some helpful tools; including PowerQuest's (now Symantec's) Partition Information viewer which will list all the fields (and data) in an MSWIN4.1 BIOS Parameter Block (BPB).
"Hex Dump" of a Sample MSWIN4.1 BPB: 00B0 00 02 08 20 00 ... . 0010 02 00 00 00 00 F8 00 00 3F 00 80 00 3F 00 00 00 ........?...?... 0020 C1 40 5E 00 88 17 00 00 00 00 00 00 02 00 00 00 .@^............. 0030 01 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0040 80 00 29 AC 2F 37 B9 4D 59 5F 43 5F 44 52 49 56 ..) /7.MY_C_DRIV 0050 45 20 46 41 54 33 32 20 20 20 EFAT32 0 1 2 3 4 5 6 7 8 9 A B C D E F |
The following
table lists values taken from the "Hex Dump" shown above. Offsets
for each field are referenced from the beginning (00h) of the Boot Record
(which is located at Absolute Sector 63 on most hard disks). Microsoft®
made this BPB inconsistent with previous versions by inserting six
new fields after the Double-Word located at offset 20h, and then moving
six of the original fields (which had been located at 24h through 3Dh;
ever since the introduction of MS-DOS V4) all the way to the end of
the BPB (starting at 40h). This seems like a weird way
to handle those fields! (I've outlined the new fields with a
blue border and those which were moved to
the end of the BPB with a red border in the
Table below.)
The yellow colored fields contain data that may
vary from one computer to the next, whereas, the data in
the red and gray fields
should never vary between MSWIN4.1 Systems. The data in the
green colored fields might possibly be different under some circumstances,
but normally should remain the same as shown below.
Table 1. How to Interpret Data from the BIOS Parameter
Block:
Offset | Length | Hex Data | Decimal Equiv. or Meaning | Description |
---|---|---|---|---|
0Bh | Word | 0200 | 512 | Sector Size (in bytes) |
For Reference, see here. | " This value may take on only the following values: 512, 1024, 2048 or 4096. If maximum compatibility is desired, only the value 512 should be used. There is a lot of FAT code in the world that is basically "hard wired" to 512 bytes per sector and doesn�t bother to check this field to make sure it is 512. Microsoft operating systems will properly support 1024, 2048, and 4096, but these values are not recommended." | |||
0Dh | Byte | 08 | 8 | Sectors per Cluster; so Cluster size here = 4 kb |
Reference | " Number of sectors per allocation unit. This value must be a power of 2 that is greater than 0. The legal values are 1, 2, 4, 8, 16, 32, 64, and 128. Note however, that a value should never be used that results in a "bytes per cluster" value [Sector size * Sectors per Cluster] greater than 32K (32 * 1024). There is a misconception that values greater than this are OK. Values that cause a cluster size greater than 32K bytes do not work properly; do not try to define one. Some versions of some systems allow 64K bytes per cluster value. Many application setup programs will not work correctly on such a FAT volume." | |||
0Eh | Word | 0020 | 32 | Reserved Sectors ( including Boot Record beginning at Logical Sector 0 ) Thus, the 1st FAT begins at Logical Sector 32 or at Absolute Sector 62 + 33 sectors = Absolute Sector 95. |
10h | Byte | 02 | 2 | FATs (including copies) |
11h | Word | 0000 | N/A | Maximum Root Directory Entries (Must be set to zero for FAT32 volumes) |
13h | Word | 0000 | N/A | Total Sectors (if <
32MB) (Must be set to zero for FAT32 volumes) |
15h | Byte | F8 | "Fixed Disk" | Media Descriptor ID |
16h | Word | 0000 | N/A | Sectors per FAT (Must be set to zero for FAT32 volumes) |
18h | Word | 003F | 63 | Sectors per Track |
1Ah | Word | 0080 | 128 | Number of Heads (Sides). The most common value for drives today is: 255 heads (cf. note). |
1Ch | Double Word | 0000003F | 63 | Number of Hidden Sectors (Cyl=0 Head=0) |
In the case of the first
(Primary) partition of an HDD or the first Logical
drive in an Extended partition, this value will be 63
sectors. However, in the case of a 2nd, 3rd or 4th Primary partition
or two or more Logical drives, those volumes will have a value
here that includes the sector count of all the partitions in front of
them (for Primary partitions) or to the
beginning of the Extended partition (for Logical volumes).
The word "hidden" in this term is, of course, a misnomer
for any partition other than the first one! |
||||
Reference |
" Count of hidden sectors preceding the partition that contains this FAT volume. This field is generally only relevant for media visible on interrupt 0x13. This field should always be zero on media that are not partitioned. Exactly what value is appropriate is operating system specific." |
|||
20h | Double Word | 005E40C1 | 6,176,961 | Total Number of Sectors |
|
|
The next two fields are not part of the BPB; they're located in a separate area, in the Boot Record's Second Sector. They contain some highly variable FAT32 File System data which may be of interest to you:
"Hex Dump" from the very beginning and the end of 2nd sector (Logical Sector 1):
7E00 52 52 61 41 00 00 00 00 00 00 00 00 00 00 00 00 RRaA............ .... 01E4 72 72 41 61 EF 87 04 00 05 1C 09 00 rrAa........ 01F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA ..............U. 0 1 2 3 4 5 6 7 8 9 A B C D E F |
The hex digits "52 52 61 41" (or "RRaA") in that order at the very beginning of the sector are used by the OS to identify this sector as the FSInfo Sector. The hex digits "72 72 41 61" (or "rrAa") in that order at offsets 01E4h through 01E7h are used by the OS to identify the beginning of the following data within the the FSInfo Sector:
Offset in 2nd Sector | Length | Hex Data | Decimal Equiv. | Description |
---|---|---|---|---|
1E8h | Double Word | 000487EF | 296,943 | Free Clusters on Disk |
Reference | " Contains the last known free cluster count on the volume. If the value is 0xFFFFFFFF, then the free count is unknown and must be computed. Any other value can be used, but is not necessarily correct. It should be range checked at least to make sure it is [less than or equal to the] volume cluster count. " | |||
1ECh | Double Word | 00091C05 | 596,997 | Next Available Cluster |
Reference | " This is a hint for the FAT driver. It indicates the cluster number at which the driver should start looking for free clusters. Because a FAT32 FAT is large, it can be rather time consuming if there are a lot of allocated clusters at the start of the FAT and the driver starts looking for a free cluster starting at cluster 2. Typically this value is set to the last cluster number that the driver allocated. If the value is 0xFFFFFFFF, then there is no hint and the driver should start looking at cluster 2. Any other value can be used, but should be checked first to make sure it is a valid cluster number for the volume." |
Since this sample disk has 4kb
clusters, the amount of free space on the disk in bytes is: 296,943 clusters x 4096 bytes/cluster =
1,216,278,528 bytes (about 1.13 GB). The cluster number (596,997)
was verified as being the next available cluster on the disk. From tests I
ran on the disk, it appears that the Windows OS updates these two locations
every time it writes data to the disk drive!
About a month later, these
locations (Offset 1E8 through 1EF hex) were checked again and found to
contain: DF EB 03 00 54 0A 0B 00
which means a free space of: 256,991 clusters x
4096 bytes/cluster = 1,052,635,136 bytes (about 0.97 GB); the
next available cluster being: the 723,540th cluster.
_______________
*
BPB Detailed Notes Reference:
FAT: General Overview of On-Disk Format
Version 1.02, May 5, 1999. A Hardware White Paper by Microsoft
Corporation. [The PDF Document Information gives the title as: "fatgen102.PDF"
and "HWDEV" is listed as the Author. File size: 109,659 bytes, and
dated: Monday, July 26, 1999 5:36:48 PM ]
A revision of the same
Hardware White Paper was produced by Microsoft Corporation
over a year later with the following bibliographic data:
Microsoft Extensible Firmware Initiative /
FAT32 File System Specification
FAT: General Overview of On-Disk Format
Version 1.03, December 6, 2000. [ The PDF Document Information
gives the title as: "FAT: General Overview of On-Disk Format" (making
it difficult to know what the file itself should be called), "Microsoft"
is listed as the Author with the Subject as: "FAT on disk format".
The date is give as: 12/11/2000 9:51:19AM, Created by Microsoft Word 9.0 with
a file size of: 168,960 bytes.]
I have, however, also found a self-extracting .ZIP file entitled:
FATGEN103.exe (90,488 bytes) with a Microsoft digitally signed
signature (using VeriSign,Inc.) that can be viewed under Windows' file
'Properties' and dated: Friday, November 30, 2001 2:16:35PM. It contains
the original MS-Word 9.0 .DOC file from which the PDF file above
was produced.
Here's a disassembled copy of the code (; with comments) after being loaded into memory by the MBR at 0000:7C00 (An asterisk '*' in front of any Assembly Instruction listed below means that the instruction cannot be disassembled correctly by MS-DEBUG):
7C00 EB58 JMP 7C5A ; Jump over BPB (BIOS Parameter ; Block) to beginning of code. 7C02 90 NOP ; Used later as a FLAG byte for ; Extended INT 13 Disk Func.'s ; (See instruction at: 7CADh). ; 7C03 thru 7C0A 'MSWIN4.1' System Name or OEM ID. (Some think ; this is part of the BPB; it's not!) ; ; 7C0B thru 7C59 BIOS Parameter Block (BPB) See text above for detailed ; explanation of each parameter field ; in the BPB. 7C5A FA CLI ; Disable maskable Interrupts 7C5B 33C9 XOR CX,CX ; Zero out both the Counter and 7C5D 8ED1 MOV SS,CX ; Stack Segment Registers. 7C5F BCF87B MOV SP,7BF8 ; Set Stack Pointer to 0000:7BF8 ; because 7BF8-7BFF are used for ; data locations below. 7C62 8EC1 MOV ES,CX ; Zero out the Extra Segment. 7C64 BD7800 MOV BP,0078 ; Set Base Pointer to 78h. This ; points to the Memory location ; which holds a pointer to the ; Floppy Drive Parameter Table. 7C67 C57600 LDS SI,[BP+00] ; Load Segment:Offset Pointer 7C6A 1E PUSH DS ; Save Data Segment, 7C6B 56 PUSH SI ; Source Index, 7C6C 16 PUSH SS ; StackSegment and 7C6D 55 PUSH BP ; BP values on the STACK. 7C6E BF2205 MOV DI,0522 ; Destination Index <- 522h. 7C71 897E00 MOV [BP+00],DI ; Make sure that the vector to the ; Floppy Drive Parameter Table is ; 0000:0522; and since ... 7C74 894E02 MOV [BP+02],CX ; CX=0, make Segment for the drv. ; Parameter Table vector = 0000: 7C77 B10B MOV CL,0B ; CL = 11 (bytes to move). 7C79 FC CLD ; Clear Direction Flag 7C7A F3 REPZ ; REPeat unless Zero ; (unless ZF=0 after an iteration). 7C7B A4 MOVSB ; Copy one byte at a time. 7C7C 8ED9 MOV DS,CX ; Data Segment = 0000: 7C7E BD007C MOV BP,7C00 ; Base Pointer set to 7C00, where ; our BPB data is now located. 7C81 C645FE0F MOV BYTE PTR [DI-02],0F 7C85 8B4618 MOV AX,[BP+18] ; [7C18](Sectors/Track) -> AX. 7C88 8845F9 MOV [DI-07],AL 7C8B 384E40 CMP [BP+40],CL ; Comp [7C40](DskDrvID) & 00. 7C8E 7D25 JGE 7CB5 7C90 8BC1 MOV AX,CX ; 7C92 99 CWD ; Convert AX (Word) to DX:AX 7C93 BB0007 MOV BX,0700 ; 7C96 E89700 CALL 7D30 7C99 721A JB 7CB5 ;(or jc ; Jump if carry Set) 7C9B 83EB3A SUB BX,3A ; 7C9E 66A11C7C * MOV EAX,DS:7C1C ; () 7CA2 663B07 * CMP EAX,[BX] ; 7CA5 8A57FC MOV DL,[BX-04] ; 7CA8 7506 JNZ 7CB0 ; If this line is changed to: ; B20E MOV DL,0E ; then boot code is forced to always use Extended INT 13 Disk Functions! 7CAA 80CA02 OR DL,02 7CAD 885602 MOV [BP+02],DL ; ([7C00+2] -> 02h) This FLAG ; setting indicates that Extended ; INT 13 Disk Func.'s can be used. 7CB0 80C310 ADD BL,10 7CB3 73ED JNB 7CA2 ; (or jnc ; Jump if carry=0) 7CB5 BF0200 MOV DI,0002 7CB8 837E1600 CMP WORD PTR [BP+16],00 ; Comp. [7C16](should be ; zero) with 00; if not, 7CBC 7545 JNZ 7D03 ; Display Error Message! 7CBE 8B461C MOV AX,[BP+1C] ; [7C1C](Lower half; 2 bytes of ; Hidden Sectors) -> AX: 7CC1 8B561E MOV DX,[BP+1E] ; [7C1E] Uppper half -> DX. 7CC4 B90300 MOV CX,0003 7CC7 49 DEC CX 7CC8 40 INC AX 7CC9 7501 JNZ 7CCC 7CCB 42 INC DX 7CCC BB007E MOV BX,7E00 7CCF E85F00 CALL 7D31 7CD2 7326 JNB 7CFA ; (or jnc ; Jump if carry=0) 7CD4 B0F8 MOV AL,F8 7CD6 4F DEC DI 7CD7 741D JZ 7CF6 7CD9 8B4632 MOV AX,[BP+32] ; [7C32](Backup Sectors) 7CDC 33D2 XOR DX,DX 7CDE B90300 MOV CX,0003 7CE1 3BC8 CMP CX,AX 7CE3 771E JA 7D03 ; Display Error Message 7CE5 8B760E MOV SI,[BP+0E] ; [7C0E](Reserved Sectors) 7CE8 3BCE CMP CX,SI 7CEA 7317 JNB 7D03 ; Display Error Message ; (or jae ; jump if > or =) 7CEC 2BF1 SUB SI,CX 7CEE 03461C ADD AX,[BP+1C] ; [7C1C](Lower half; 2 bytes of ; Hidden Sectors) -> AX: 7CF1 13561E ADC DX,[BP+1E] ; [7C1E] Uppper half -> DX. 7CF4 EBD1 JMP 7CC7 7CF6 730B JNB 7D03 ; Display Error Message 7CF8 EB27 JMP 7D21 7CFA 837E2A00 CMP WORD PTR [BP+2A],+00 7CFE 7703 JA 7D03 ; Display Error Message 7D00 E9FD02 JMP 8000 ; Jump to the code in 3rd sector. ; ==================================================================== ; Display Error Message S U B R O U T I N E : ; ==================================================================== 7D03 BE7E7D MOV SI,7D7E ; Message offset (03) ; After 7D08, SI=7D82 -> 0D, ; 0A,"Invalid system disk" 7D06 AC LODSB ; [DS:SI] -> AL 7D07 98 CBW ; Convert Byte to Word 7D08 03F0 ADD SI,AX ; 7D0A AC LODSB ; String [DS:SI] -> AL 7D0B 84C0 TEST AL,AL ; When 00 at 7DD5 is found, 7D0D 7417 JZ 7D26 ; execution jumps to 7D26. 7D0F 3CFF CMP AL,FF 7D11 7409 JZ 7D1C ; Continue with last line ; (or je ; jump if equal) ; of either Error Message 7D13 B40E MOV AH,0E 7D15 BB0700 MOV BX,0007 7D18 CD10 INT 10 7D1A EBEE JMP 7D0A 7D1C BE817D MOV SI,7D81 ; Message offset (27) 7D1F EBE5 JMP 7D06 ; After 7D08, SI=7DA9 -> 0D, ; 0A,"Replace the disk, and ; then press any key",0D,0A. 7D21 BE7F7D MOV SI,7D7F ; Message offset (18) 7D24 EBE0 JMP 7D06 ; After 7D08, SI=7D98 -> 0D, ; 0A,"Disk I/O error" 7D26 98 CBW ; Convert Byte to Word 7D27 CD16 INT 16 ; Wait until getting a key- ; stroke from Keyboard. 7D29 5E POP SI 7D2A 1F POP DS 7D2B 668F04 * POP DWord PTR [SI] 7D2E CD19 INT 19 ; If a key was pressed, then ; Start over again with ; System BOOTSTRAP LOADER. ; ===================================================================== ; Read Disk S U B R O U T I N E S : ; ===================================================================== ; Entry Point to Read MBR (Master Boot Record) Sector 7D30 41 INC CX ; Now CX = 1 (sector) for MBR ; Normal Entry Point for Reading Sectors from Hard Disk 7D31 56 PUSH SI 7D32 666A00 * PUSH DWord Ptr 0 7D35 52 PUSH DX 7D36 50 PUSH AX 7D37 06 PUSH ES 7D38 53 PUSH BX 7D39 6A01 * PUSH 1 7D3B 6A10 * PUSH 10 7D3D 8BF4 MOV SI,SP 7D3F 60 * PUSHA ; Save ALL Registers! 7D40 807E020E CMP BYTE PTR [BP+02],0E 7D44 7504 JNZ 7D4A ; jne -> jump if not equal 7D46 B442 MOV AH,42 7D48 EB1D JMP 7D67 7D4A 91 XCHG CX,AX 7D4B 92 XCHG DX,AX 7D4C 33D2 XOR DX,DX 7D4E F77618 DIV WORD PTR [BP+18] 7D51 91 XCHG CX,AX 7D52 F77618 DIV WORD PTR [BP+18] 7D55 42 INC DX 7D56 87CA XCHG CX,DX 7D58 F7761A DIV WORD PTR [BP+1A] 7D5B 8AF2 MOV DH,DL ; DH = Head Number, 7D5D 8AE8 MOV CH,AL ; CH = Cylinder, 7D5F C0CC02 * ROR AH,02 ; (Rotate Bits Right by 2 bytes) 7D62 0ACC OR CL,AH ; CL = Sector, for... 7D64 B80102 MOV AX,0201 ; Function 02h of INT 13: 7D67 8A5640 MOV DL,[BP+40] ; DL = Drive; 7D6A CD13 INT 13 ; "Read Sector(s) into Memory" ; at ES:BX 7D6C 61 * POPA ; Restore all Registers 7D6D 8D6410 LEA SP,[SI+10] 7D70 5E POP SI 7D71 720A JB 7D7D ; (or jc -> Jump if carry Set) 7D73 40 INC AX 7D74 7501 JNZ 7D77 7D76 42 INC DX 7D77 035E0B ADD BX,[BP+0B] 7D7A 49 DEC CX 7D7B 75B4 JNZ 7D31 7D7D C3 RET
;=======================================================================
;
; The following code is located in...
; The 3rd Sector of this VBR
;
;=======================================================================
8000 FA CLI ; Disable interrupts
8001 660FB64610 * MOVZX EAX,BYTE PTR [BP+10] ; MOV w/ZERO extend
8006 668B4E24 * MOV ECX,[BP+24]
800A 66F7E1 * MUL ECX ; DX:AX = REG * AX
800D 6603461C * ADD EAX,[BP+1C]
8011 660FB7560E * MOVZX EDX,WORD PTR [BP+0E] ; MOV w/ZERO extend
8016 6603C2 * ADD EAX,EDX
8019 33C9 XOR CX,CX ; Zero-out CX register
801B 668946FC * MOV [BP-04],EAX
801F 66C746F8FFFFFFFF * MOV DWORD PTR [BP-08],FFFFFFFF
8027 FA CLI ; Disable Interrupts
8028 668B462C * MOV EAX,[BP+2C]
802C 6683F802 * CMP EAX,02
8030 0F82CFFC * JB 7D03 ; Jump if below
8034 663DF8FFFF0F * CMP EAX,0FFFFFF8 ; 0FFFFFF8
803A 0F83FCC5 * JAE 7D03 ; Jump if above or =
803E 660FA4C210 * SHLD EDX,EAX,10 ; Double shift left
; (that's by 16 bytes)
8043 FB STI ; Enable Interrupts
8044 52 PUSH DX
8045 50 PUSH AX
8046 FA CLI ; Disable Interrupts
8047 66C1E010 * SHL EAX,10 ; Shift w/ZERO Fills
; (that's 16 bytes)
804B 660FACD010 * SHRD EAX,EDX,10 ; Double Shift Right
; (that's by 16 bytes)
8050 6683E802 * SUB EAX,02
8054 660FB65E0D * MOVZX EBX,BYTE PTR [BP+0D] ; Move w/ZERO extend
8059 8BF3 MOV SI,BX
805B 66F7E3 * MUL EBX ; DX:AX = REG * AX
805E 660346FC * ADD EAX,[BP-04]
8062 660FA4C210 * SHLD EDX,EAX,10 ; Double Shift Left
; (that's by 16 bytes)
8067 FB STI ; Enable Interrupts
8068 BB0007 MOV BX,0700 ; (0000:0700=3Fh)
806B 8BFB MOV DI,BX
806D B90100 MOV CX,0001
8070 E8BEFC CALL 7D31
8073 0F82AAFC * JC 7D21 ; Jump if carry Set
8077 382D CMP [DI],CH
8079 741E JZ 8099 ; or je -> Jump if Equal
807B B10B MOV CL,0B
807D 56 PUSH SI
807E BED87D MOV SI,7DD8 ; Points to IO.SYS
8081 F3 REPZ
8082 A6 CMPSB ; Rep zf=1+cx >0 Cmp [si] to es:[di]
; repe cmpsb
8083 5E POP SI
8084 7419 JZ 809F
8086 03F9 ADD DI,CX
8088 83C715 ADD DI,15
808B 3BFB CMP DI,BX
808D 72E8 JB 8077
808F 4E DEC SI
8090 75D6 JNZ 8068
8092 58 POP AX
8093 5A POP DX
8094 E86600 CALL 80FD
8097 72AB JB 8044 ; (or jc -> Jump if Carry Set)
8099 83C404 ADD SP,04
809C E964FC JMP 7D03
809F 83C404 ADD SP,04
80A2 8B7509 MOV SI,[DI+09]
80A5 8B7D0F MOV DI,[DI+0F]
80A8 8BC6 MOV AX,SI
80AA FA CLI ; Disable Interrupts
80AB 66C1E010 * SHL EAX,10 ; Shift w/Zero Fills
; (that's 16 bytes)
80AF 8BC7 MOV AX,DI
80B1 6683F802 * CMP EAX,02
80B5 723B JB 80F2
80B7 663DF8FFFF0F * CMP EAX,0FFFFFF8
80BD 7333 JNB 80F2 ; or jae
80BF 6648 * DEC EAX
80C1 6648 * DEC EAX
80C3 660FB64E0D * MOVZX ECX,BYTE PTR SS:[BP+0D] ; MOV w/ZERO extend
80C8 66F7E1 * MUL ECX ; DX:AX = REG * AX
80CB 660346FC * ADD EAX,[BP-04]
80CF 660FA4C210 * SHLD EDX,EAX,10 ; Double SHIFT LEFT
; (that's by 16 bytes)
80D4 FB STI ; Enable Interrupts
80D5 BB0007 MOV BX,0700 ; (0000:0700=3Fh)
80D8 53 PUSH BX
80D9 B90400 MOV CX,0004
80DC E852FC CALL 7D31
80DF 5B POP BX
80E0 0F823DFC * JC 7D21 ; Jump if Carry Set
80E4 813F4D5A CMP WORD PTR [BX],5A4D
80E8 7508 JNZ 80F2 ; or JNE -> Jump if Not Equal
80EA 81BF0002424A CMP WORD PTR DS:[BX+200],4A42 ; (0000:0200=0)
80F0 7406 JZ 80F8 ; or JE -> Jump if Equal
80F2 BE807D MOV SI,7D80 ; Message offset (01)
80F5 E90EFC JMP 7D06 ; After 7D08, SI=7D82 -> 0D,
; 0A,"Invalid system disk"
80F8 EA00027000 JMP FAR PTR 0070:0200 ; (or 0000:0900)
; =====================================================================
; S U B R O U T I N E
; =====================================================================
80FD 03C0 ADD AX,AX
80FF 13D2 ADC DX,DX
8101 03C0 ADD AX,AX
8103 13D2 ADC DX,DX
8105 E81800 CALL 8120
8108 FA CLI ; Disable Interrupts
8109 26668B01 * MOV EAX,ES:[BX+DI]
810D 6625FFFFFF0F * AND EAX,0FFFFFFF
8113 660FA4C210 * SHLD EDX,EAX,10 ; Double Shift Left
; (that's by 16 bytes)
8118 663DF8FFFF0F * CMP EAX,0FFFFFF8
811E FB STI ; Enable Interrupts
811F C3 RET
; =====================================================================
; S U B R O U T I N E
; =====================================================================
8120 BF007E MOV DI,7E00
8123 FA CLI ; Disable Interrupts
8124 66C1E010 * SHL EAX,10 ; Shift w/ZEROs Fill
8128 660FACD010 * SHRD EAX,EDX,10 ; Double Shift Right
812D 660FB74E0B * MOVZX ECX,WORD PTR [BP+0B] ; MOV w/ZERO Extend
8132 6633D2 * XOR EDX,EDX ; Zero-out EDX Register
8135 66F7F1 * DIV ECX ; AX,DX (Rem=DX:AX/REG)
8138 663B46F8 * CMP EAX,[BP-8]
813C 7444 JE 8182 ; Jump if equal
813E 668946F8 * MOV [BP-8],EAX
8142 6603461C * ADD EAX,[BP+1C]
8146 660FB74E0E * MOVZX ECX,WORD PTR [BP+0E] ; MOV w/ZERO Extend
814B 6603C1 * ADD EAX,ECX
814E 660FB75E28 * MOVZX EBX,WORD PTR [BP+28] ; MOV w/ZERO Extend
8153 83E30F AND BX,0F
8156 7416 JZ 816E ; Jump if Zero
8158 3A5E10 CMP BL,[BP+10]
815B 0F83A4FB JNB 7D03 ; or JAE -> Jump if Above or =
815F 52 PUSH DX
8160 668BC8 * MOV ECX,EAX
8163 668B4624 * MOV EAX,[BP+24]
8167 66F7E3 * MUL EBX ; DX:AX = REG * AX
816A 6603C1 * ADD EAX,ECX
816D 5A POP DX
816E 52 PUSH DX
816F 660FA4C210 * SHLD EDX,EAX,10 ; Double Shift Left
; (that's by 16 bytes)
8174 FB STI ; Enable Interrupts
8175 8BDF MOV BX,DI
8177 B90100 MOV CX,1
817A E8B4FB CALL 7D31
817D 5A POP DX
817E 0F829FFB JC 7D21 ; Jump if carry Set
8182 FB STI ; Enable Interrupts
8183 8BDA MOV BX,DX
8185 C3 RET
Location
of Data and
Error Messages in Memory
From Logical Sector 0: 7D7E 03 18 .. 7D80 01 27 0D 0A 49 6E 76 61 6C 69 64 20 73 79 73 74 ....Invalid syst 7D90 65 6D 20 64 69 73 6B FF 0D 0A 44 69 73 6B 20 49 em disk...Disk I 7DA0 2F 4F 20 65 72 72 6F 72 FF 0D 0A 52 65 70 6C 61 /O error...Repla 7DB0 63 65 20 74 68 65 20 64 69 73 6B 2C 20 61 6E 64 ce the disk, and 7DC0 20 74 68 65 6E 20 70 72 65 73 73 20 61 6E 79 20 then press any 7DD0 6B 65 79 0D 0A 00 00 00 49 4F 20 20 20 20 20 20 key.....IO 7DE0 53 59 53 4D 53 44 4F 53 20 20 20 53 59 53 7E 01 SYSMSDOS SYS~. 7DF0 00 57 49 4E 42 4F 4F 54 20 53 59 53 00 00 55 AA .WINBOOT SYS..U. 0 1 2 3 4 5 6 7 8 9 A B C D E F |
From Logical Sector 1 (the bytes "52 52 61 41" or "RRaA" are used by the system to confirm/identify the beginning of the Boot Record's Second sector):
7E00 52 52 61 41 00 00 00 00 00 00 00 00 00 00 00 00 RRaA............ 7FE0 00 00 00 00 72 72 41 61 EF 87 04 00 05 1C 09 00 ....rrAa........ 7FF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA ..............U.
From Logical Sector 2:
81F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA ..............U.
Note that both
of these sectors end with the usual "end of sector" Signature
(or Magic number) the hex Word: AA55h.
Partition and Boot Record Manager
For those who don't require much support,
there are FREE programs, including an interactive MBR which
can be obtained from Mikhail Ranish: the Ranish Partition Manager and
Boot Manager
http://www.ranish.com/part/. Download the stable freeware version
2.37.12 (which includes source code), or try his latest program.
Place a floppy in your A:\
drive and run PM's Install.bat to save all the Partition information from
your drive(s) to the floppy! [ Why? Because the Partition Table data for
your particular drive(s) can NEVER be refreshed or recovered by running an
FDISK /MBR command; which simply replaces the MBR code! ]
Ranish's program, part.exe (in version 2.37.12 or part_cmd.exe in
the newer beta set), is also 'Console' enabled which means it can be used
rather effectively in Batch files too! For the details, open a DOS-Window
at the folder where part.exe exists, then enter: part -? at
the prompt (do NOT use -h as this is a command to HIDE partitions!!).
Other Free Tools
Ready for download from my own FreeTools page: FREE set of Windows tools
by PowerQuest for displaying your Partition Tables and Boot
Records... Partition Info
for Win 9x or Win NT.
If you need a Disk Editor to make any changes or simply view sectors on
your hard disks, then take this link to my FreeTools page and download the
PhysTechSoft Disk Editor
(PTSDE) Read the CAUTION NOTE before using it!!
You can write to us using this: contact
form (opens in a new window).
The
Starman's FREE TOOLS Page
MBR and Boot Records Index
The Starman's
Realm Index Page