( Note:
This Boot Record is the same exact code for:
Windows 98, Windows 98 SE, Windows ME
and even the Windows
XP Startup Diskettes! )
Web Presentation
and Text are Copyright © 2001-2005 by Daniel B. Sedory
(NOT to be reproduced in any form without Permission of
the Author !)
First,
we'll look at a disk editor view of this Boot Record as its stored on
a 1440 KiB Floppy Disk (often incorrectly called a 1.44mb floppy). Unlike hard
disks, which always have
an MBR sector
with a Partition Table, the first sector of a diskette (Absolute Sector 0 or
CHS 0,0,1) most often contains the Boot Record for a file system; though
it's not absolutely necessary. Such a diskette can
be used to boot up a PC,
if the system files for that Boot Record have been correctly stored on it. Thus,
floppy diskettes may be thought of as a single hard disk volume when
they contain a file system.
Since
these are floppy (not hard) disks, you may read about Tracks
(instead of Cylinders) and Sides (instead of Heads) in discussions about
them. These terms seem to make more sense, since you can hold the removable
media in your hands and observe that its jacket (for 5.25 inch diskettes) or
hard plastic shell (for 3.5-inch diskettes) contains a circular disc
having two sides without ever having to think about the heads or mechanical
parts inside the floppy drive.
(See Examination
of the Code below, to learn where the BIOS
places the Boot Record in Memory just before it is executed.)
BPB Absolute Sector 0 (Track 0, Side 0, Sector 1) | OEM System Name 0 1 2 3 4 5 6 7 8 9 A B C D |E F | 0000: EB 3C 90 4D 53 57 49 4E 34 2E 31 00 02 01 01 00 .<.MSWIN4.1..... 0010: 02 E0 00 40 0B F0 09 00 12 00 02 00 00 00 00 00 ...@............ 0020: 00 00 00 00 00 00 29 21 6C 15 27 42 4F 4F 54 44 ......)!l.'BOOTD 0030: 49 53 4B 20 20 20 46 41 54 31 32 20 20 20 33 C9 ISK FAT12 3. 0040: 8E D1 BC FC 7B 16 07 BD 78 00 C5 76 00 1E 56 16 ....{...x..v..V. 0050: 55 BF 22 05 89 7E 00 89 4E 02 B1 0B FC F3 A4 06 U."..~..N....... 0060: 1F BD 00 7C C6 45 FE 0F 38 4E 24 7D 20 8B C1 99 ...|.E..8N$} ... 0070: E8 7E 01 83 EB 3A 66 A1 1C 7C 66 3B 07 8A 57 FC .~...:f..|f;..W. 0080: 75 06 80 CA 02 88 56 02 80 C3 10 73 ED 33 C9 FE u.....V....s.3.. 0090: 06 D8 7D 8A 46 10 98 F7 66 16 03 46 1C 13 56 1E ..}.F...f..F..V. 00A0: 03 46 0E 13 D1 8B 76 11 60 89 46 FC 89 56 FE B8 .F....v.`.F..V.. 00B0: 20 00 F7 E6 8B 5E 0B 03 C3 48 F7 F3 01 46 FC 11 ....^...H...F.. 00C0: 4E FE 61 BF 00 07 E8 28 01 72 3E 38 2D 74 17 60 N.a....(.r>8-t.` 00D0: B1 0B BE D8 7D F3 A6 61 74 3D 4E 74 09 83 C7 20 ....}..at=Nt... 00E0: 3B FB 72 E7 EB DD FE 0E D8 7D 7B A7 BE 7F 7D AC ;.r......}{...}. 00F0: 98 03 F0 AC 98 40 74 0C 48 74 13 B4 0E BB 07 00 .....@t.Ht...... 0100: CD 10 EB EF BE 82 7D EB E6 BE 80 7D EB E1 CD 16 ......}....}.... 0110: 5E 1F 66 8F 04 CD 19 BE 81 7D 8B 7D 1A 8D 45 FE ^.f......}.}..E. 0120: 8A 4E 0D F7 E1 03 46 FC 13 56 FE B1 04 E8 C2 00 .N....F..V...... 0130: 72 D7 EA 00 02 70 00 52 50 06 53 6A 01 6A 10 91 r....p.RP.Sj.j.. 0140: 8B 46 18 A2 26 05 96 92 33 D2 F7 F6 91 F7 F6 42 .F..&...3......B 0150: 87 CA F7 76 1A 8A F2 8A E8 C0 CC 02 0A CC B8 01 ...v............ 0160: 02 80 7E 02 0E 75 04 B4 42 8B F4 8A 56 24 CD 13 ..~..u..B...V$.. 0170: 61 61 72 0A 40 75 01 42 03 5E 0B 49 75 77 C3 03 aar.@u.B.^.Iuw.. 0180: 18 01 27 0D 0A 49 6E 76 61 6C 69 64 20 73 79 73 ..'..Invalid sys 0190: 74 65 6D 20 64 69 73 6B FF 0D 0A 44 69 73 6B 20 tem disk...Disk 01A0: 49 2F 4F 20 65 72 72 6F 72 FF 0D 0A 52 65 70 6C I/O error...Repl 01B0: 61 63 65 20 74 68 65 20 64 69 73 6B 2C 20 61 6E ace the disk, an 01C0: 64 20 74 68 65 6E 20 70 72 65 73 73 20 61 6E 79 d then press any 01D0: 20 6B 65 79 0D 0A 00 00 49 4F 20 20 20 20 20 20 key....IO 01E0: 53 59 53 4D 53 44 4F 53 20 20 20 53 59 53 7F 01 SYSMSDOS SYS.. 01F0: 00 41 BB 00 07 60 66 6A 00 E9 3B FF 00 00 55 AA .A...`fj..;...U. 0 1 2 3 4 5 6 7 8 9 A B C D E F000h through 1FFh = 200h bytes; the standard 512 bytes per sector. |
The
first three bytes of the Boot Sector are called the Jump Instruction
(though the third byte has always been a 90h;
i.e., a NOP 'No Operation' or do nothing instruction in all
the IBM® PC and Microsoft® DOS releases). [ Three bytes were
reserved here just in case any future programmer had decided to use the x86
machine code's 'Direct Jump' instruction (which begins with E9h) rather
than the 'Short' Jump's EBh; as a matter of fact, there's an example
of the E9h Jump near the end of this Boot Sector: The bytes at offsets
1F9h through 1FBh in the table above ("E9 3B FF")
when relocated to 7DF9-7DFB in Memory, have the meaning "Jump to 7D37
h." ]
What follows is
the OEM System Name which happens
to be 'MSWIN4.1' in this case,
but could be anything as far as the code is concerned [CAUTION: Any diskette
that is not write-protected, will have these bytes overwritten by any
Microsoft® Windows 9x (or later) OS; for more info see: Notes
about the "IHC" string here ].
Next we have the _ BIOS Parameter Block _ (or BPB); some of which dates back to the release of version 2.0 of (IBM®/Microsoft®) DOS. (See the special section "The BIOS Parameter Block" below, for all the details of the BPB and how to interpret its contents.)
Most of the Boot Record is executable code, but unlike previous versions, this boot record
has some of its code shoved-in at the end
of the sector! Most of the code is between offsets 3Eh through 17Eh,
but there's a subroutine at offsets 1F1h through
1FBh. The larger portion of the code is followed by some Data
Registers (note the underlined byte values with only a white background
in our display above), three error messages and the two
system-file names: IO.SYS and MSDOS.SYS; followed
by three more Data bytes.
The sector ends as usual with the Word-sized signature ID (or
Magic number) of AA55 hex (remember hex Words for Intel x86 CPUs are
stored in memory with the Lowest-byte first and the Highest-byte last to make
processing quicker).
The BIOS Parameter Block
Beginning at offset 0Bh, the BPB data on this diskette is interpreted as follows:
0 1 2 3 4 5 6 7 8 9 A B C D E F 00: 00 02 01 01 00 10: 02 E0 00 40 0B F0 09 00 12 00 02 00 00 00 00 00 20: 00 00 00 00 00 00 29 21 6C 15 27 42 4F 4F 54 44 ......)!l.'BOOTD 30: 49 53 4B 20 20 20 46 41 54 31 32 20 20 20 ISK FAT12 Hex As seen OFFSET on Disk HEX value Meaning / Description ------ ------- --------- ------------------------------------------------- 0B-0C 00 02 0200h = 512 Bytes per Sector, 0D 01 01h = 1 Sector per Cluster, 0E-0F 01 00 0001h = 1 Reserved sector (starting at Sector 0), 10 02 02h = 2 FATs on the diskette, 11-12 E0 00 00E0h = 224 possible Root Directory entries, 13-14 40 0B 0B40h = 2880 Total Sectors on the diskette, ( 2880 x 512 = 1,474,560 bytes total ), 15 F0 => Media Descriptor Byte: F0 essentially means 'Not identifiable' (this byte is more for telling the OS whether or not the media is a hard disk or a floppy disk rather than its exact size). An F8 byte means a 'Fixed Disk' (hard drive); only a few other bytes have ever been used here.* 16-17 09 00 0009h = 9 Sectors per FAT, 18-19 12 00 0012h = 18 Sectors per Track, 1A-1B 02 00 0002h = 2 Sides (or Heads). 26 29 => Extended BPB Signature Byte (if present, then the following strings will also have meaning): 27-2A xx xx xx xx = Volume Serial Number. In the example above, the S/N displays as: 2715-6C21 (a 4-byte Hex Word). 2B-35 (11 bytes) = Volume Label. 36-3B = File System ID (see discussion below). ______________ * FF=DS,8 SPT; FE=SS,8 SPT; FD=DS, 9 SPT (the 360kb diskette); FC=SS,9 SPT; F9 = DS,9 SPT (a 720kb) or DS,15 SPT. Apparently the fact that F9 could mean either of these, signaled the end of its usefulness! |
Using the data in the BPB, we can determine our
diskette has: A capacity of 1440 KiB (1,474,560 bytes), two sides and
18 Sectors per Track; that should mean we're looking at a standard 3.5-inch
'DSHD' Double-Sided High Density diskette. [The
actual space available for user data depends upon the file system though; so,
under FAT12, you'd have to subtract the area used for the boot
record (1 sector), both FATs (9 sectors each = 18) and
the Directory (14 sectors), which leaves us with 2,847 sectors
(2,880 - 33) or 1,457,664 bytes; 1423.5 KiB.]
The bytes from offsets 1Ch through 1Fh are a Double-Word
containing the 'Number of Hidden Sectors.' Practically every floppy diskette
you'll ever see will only have zeros here; as will the next four bytes (offsets
20h through 23h), another Double-Word, used in DOS
versions 3 (and above) for disk partitions having more
than 65,535 sectors! And if that's the case, then the bytes at offsets 13h-14h
must be zero.
Beginning with DOS version 4.0, if the byte at offset 26h
is a 29h, then the next four bytes (offsets
27h through 2Ah) will contain a Serial Number
based on the date and time the diskette was formatted; if necessary, these bytes
(along with the OEM ID and Volume Label) can be changed by a disk editor. If
the 29 Extended BPB Signature Byte
is present, then the bytes at offsets 2Bh through
35h may contain an 11-byte Volume Label
and the bytes at offsets 36h through 3Dh should contain the File
System ID of: "FAT12 ";
including three trailing space bytes (20h).
If you require more information on the BPB, see the TABLE on this page:
The MSWIN4.1 Hard Disk Boot Record.
If you see an asterisk ( * ) on the line, this indicates the instruction requires a CPU higher than an Intel 8088/8086 (and also that MS-DEBUG cannot decode the meaning of this instruction). The first sector of the floppy disk is copied into Memory at location 0000:7C00 by a 'bootstrap' routine in the computer's BIOS chip.
7C00 EB3C JMP 7C3E ; Jump over the BPB. 7C02 90 NOP ; Do nothing, however, this ; location is used at 7C85 ; and 7D61 for temp. data. ========================================================================= OEM string and BIOS Parameter Block Data 0 1 2 3 4 5 6 7 8 9 A B C D E F 7C00 90 4D 53 57 49 4E 34 2E 31 00 02 01 01 00 MSWIN4.1..... 7C10 02 E0 00 40 0B F0 09 00 12 00 02 00 00 00 00 00 ...@............ 7C20 00 00 00 00 00 00 29 21 6C 15 27 42 4F 4F 54 44 ......)!l.'BOOTD 7C30 49 53 4B 20 20 20 46 41 54 31 32 20 20 20 ISK FAT12 0 1 2 3 4 5 6 7 8 9 A B C D E F ========================================================================= ; Both the Stack and Extra Segments are set to zero and the Stack Pointer ; is set to allow room for temporary data in memory locations 0:7BFC and ; following (7BFC-7BFF; plus 7C00 through 7C0A if necessary). 7C3E 33C9 XOR CX,CX ; Zero-out Count Register and set 7C40 8ED1 MOV SS,CX ; Stack Segment register to zero. 7C42 BCFC7B MOV SP,7BFC ; Stack Pointer is now: 0000:7BFC 7C45 16 PUSH SS ;| 7C46 07 POP ES ;| Make sure Extra Segment = zero. ; The next group of instructions 1) Load a far pointer (four bytes) from ; the contents of SS:[BP+00] through SS:[BP+03]; which is the Interrupt ; Vector for INT 1E, into DS:SI. Then all the registers involved in this ; LDS instruction have their contents pushed onto the Stack: 7C47 BD7800 MOV BP,0078 ; 0078h --> BP 7C4A C57600 LDS SI,[BP+00] ; LDS SI,dword ptr [bp] 7C4D 1E PUSH DS 7C4E 56 PUSH SI 7C4F 16 PUSH SS 7C50 55 PUSH BP ; The following code copies data from the Diskette Drive Parameters table ; which a far pointer (Segment:Offset) in the Interrupt Vector Table (IVT) ; at 0:0078 and following points to; for later use. 7C51 BF2205 MOV DI,0522 7C54 897E00 MOV [BP+00],DI ; 0522h -> 7C57 894E02 MOV [BP+02],CX ; MOV word ptr [bp+02],cx 7C5A B10B MOV CL,0B 7C5C FC CLD 7C5D F3 REPZ 7C5E A4 MOVSB ; repe movsb es:[di],ds:[si] 7C5F 06 PUSH ES 7C60 1F POP DS 7C61 BD007C MOV BP,7C00 7C64 C645FE0F MOV BYTE PTR [DI-02],0F 7C68 384E24 CMP [BP+24],CL ; [7C24] 7C6B 7D20 JGE 7C8D ; or: JNL 7C8D 7C6D 8BC1 MOV AX,CX 7C6F 99 CWD ; Convert Word to DoubleWord 7C70 E87E01 CALL 7DF1 7C73 83EB3A SUB BX,+3A 7C76 66A11C7C * mov eax,[7C1C] 7C7A 663B07 * cmp eax,dword ptr [bx] 7C7D 8A57FC MOV DL,[BX-04] 7C80 7506 JNZ 7C88 7C82 80CA02 OR DL,02 7C85 885602 MOV [BP+02],DL 7C88 80C310 ADD BL,10 7C8B 73ED JNB 7C7A 7C8D 33C9 XOR CX,CX 7C8F FE06D87D INC BYTE PTR [7DD8] ; Points to IO.SYS ; Note: This changes the name from IO.SYS to JO.SYS 7C93 8A4610 MOV AL,[BP+10] ; [7C10]=02 here. 7C96 98 CBW ; Convert Byte to Word 7C97 F76616 MUL WORD PTR [BP+16] ; W[7C16]=0009 here, so ; AX becomes 12h (or 18). 7C9A 03461C ADD AX,[BP+1C] ; [7C1C] 7C9D 13561E ADC DX,[BP+1E] ; [7C1E] 7CA0 03460E ADD AX,[BP+0E] ; W[7C0E]=0001 here, so ; AX becomes 13h (or 19). ; We now have the number of Sector per FAT (0009) times 2 = 18 plus the ; 1 sector reserved for the Boot Record itself = 19 in the AX register. 7CA3 13D1 ADC DX,CX 7CA5 8B7611 MOV SI,[BP+11] ; W[7C11]=00E0h= possible # ; of Root Directory entries. 7CA8 60 * pusha ; Push Registers on Stack 7CA9 8946FC MOV [BP-04],AX ; Temporarily store values 7CAC 8956FE MOV [BP-02],DX ; of AX and DX here. 7CAF B82000 MOV AX,0020 ; Size of Directory Entries. ; At this point, AX is 20h (or 32), which is the size of each (file) entry ; in the Root Directory; of which there can be a total of 224 (0Eh in SI). 7CB2 F7E6 MUL SI ; After multiplying, AX contains 1C00h (7,168) as the number of bytes in ; the maximum possible number of Root Directory entries. At 7CBA, we divide ; by the Bytes per Sector value (0200h) to arrive at the number of sectors ; being used by the Root Directory of this file system: 0Eh (or 14). And ; finally, the instruction at 7CBC, gives us a total of 21h (or 33) sectors ; (in [BP-04]=[7BFC]) for all the sectors used by the file system. 7CB4 8B5E0B MOV BX,[BP+0B] ; W[7C0B]=0200h (or 512). 7CB7 03C3 ADD AX,BX ; AX -> 1C00h + 0200h = 1E00h. 7CB9 48 DEC AX ; AX = 1DFFh. 7CBA F7F3 DIV BX ; AX -> 1DFFh/0200h = 000Eh. 7CBC 0146FC ADD [BP-04],AX ; W[7BFC] -> 0Eh + 13h = 21h. 7CBF 114EFE ADC [BP-02],CX 7CC2 61 * popa ; Pop Registers from Stack 7CC3 BF0007 MOV DI,0700 7CC6 E82801 CALL 7DF1 7CC9 723E JB 7D09 ; -> "Disk I/O error" 7CCB 382D CMP [DI],CH 7CCD 7417 JZ 7CE6 7CCF 60 * pusha ; Push Registers on Stack 7CD0 B10B MOV CL,0B 7CD2 BED87D MOV SI,7DD8 ; Points to JO.SYS 7CD5 F3 REPZ 7CD6 A6 CMPSB ; repe cmpsb es:[di],ds:[si] 7CD7 61 * popa ; Pop Registers from Stack 7CD8 743D JZ 7D17 7CDA 4E DEC SI 7CDB 7409 JZ 7CE6 7CDD 83C720 ADD DI,+20 7CE0 3BFB CMP DI,BX 7CE2 72E7 JB 7CCB 7CE4 EBDD JMP 7CC3 7CE6 FE0ED87D DEC BYTE PTR [7DD8] ; Becomes IO.SYS again. 7CEA 7BA7 JPO 7C93 ; jnp 7C93 ; If execution ends up here, IO.SYS could not be found on the diskette! 7CEC BE7F7D MOV SI,7D7F ; [7D7F]=03 ; If the following code is entered from above, then SI becomes 7D80 ; after LODSB at 7CEF and AL=03, so SI + AX = 7D83 and DS:SI points to ; -> 0Dh, 0Ah, "Invalid system disk", FFh at 7CF3 for display routine. 7CEF AC LODSB ; lodsb al, ds:[si] 7CF0 98 CBW ; Convert byte to Word. 7CF1 03F0 ADD SI,AX ; 7CF3 AC LODSB ; lodsb al, ds:[si] 7CF4 98 CBW ; Convert byte to Word. 7CF5 40 INC AX ; INC FFh -> 00h 7CF6 740C JZ 7D04 7CF8 48 DEC AX 7CF9 7413 JZ 7D0E 7CFB B40E MOV AH,0E ; Video Function 0Eh 7CFD BB0700 MOV BX,0007 ; Page 0, Normal White on 7D00 CD10 INT 10 ; Black 'Tele-type Output' ; AL = character to write. 7D02 EBEF JMP 7CF3 ; Display another character. ; When the code jumps to 7CEF from 7D07 below, SI will become 7D83 after ; the first LODSB and AL=27h, so SI + AX = 7DAA and DS:SI will point to ; -> 0Dh, 0Ah, "Replace the disk, and then press any key", 0Dh, 0Ah, 00h. ; After that, the routine will fall through to 7D0E and wait to reboot! 7D04 BE827D MOV SI,7D82 ; [7D82] = 27h (or 39). 7D07 EBE6 JMP 7CEF ; When the code jumps to 7CEF from 7D0C below, SI will become 7D81 after ; the first LODSB and AL=18h, then SI + AX = 7D99 and DS:SI will point to ; -> 0Dh, 0Ah, "Disk I/O error", FFh. 7D09 BE807D MOV SI,7D80 ; [7D80]=18h (or 24). 7D0C EBE1 JMP 7CEF 7D0E CD16 INT 16 ; Get a Keystroke from Keyboard: ; Waits for user to press a key in ; order to try booting from another ; floppy disk (or hard drive). 7D10 5E POP SI 7D11 1F POP DS 7D12 668F04 * pop dword ptr [si] 7D15 CD19 INT 19 ; Start over again with ; System BOOTSTRAP LOADER.
7D17 BE817D MOV SI,7D81 ; [7D81] = 01 7D1A 8B7D1A MOV DI,[DI+1A] 7D1D 8D45FE LEA AX,[DI-02] 7D20 8A4E0D MOV CL,[BP+0D] 7D23 F7E1 MUL CX 7D25 0346FC ADD AX,[BP-04] 7D28 1356FE ADC DX,[BP-02] 7D2B B104 MOV CL,04 7D2D E8C200 CALL 7DF2 7D30 72D7 JB 7D09 ; -> "Disk I/O error" 7D32 EA00027000 JMP FAR PTR 0070:0200 ; or 0900h.
7D37 52 PUSH DX 7D38 50 PUSH AX 7D39 06 PUSH ES 7D3A 53 PUSH BX 7D3B 6A01 * push 0001 7D3D 6A10 * push 0010 7D3F 91 XCHG CX,AX 7D40 8B4618 MOV AX,[BP+18] ; [7C18] = 18 Sectors/Track 7D43 A22605 MOV [0526],AL 7D46 96 XCHG SI,AX 7D47 92 XCHG DX,AX 7D48 33D2 XOR DX,DX 7D4A F7F6 DIV SI 7D4C 91 XCHG CX,AX 7D4D F7F6 DIV SI 7D4F 42 INC DX 7D50 87CA XCHG CX,DX 7D52 F7761A DIV WORD PTR [BP+1A] ; [7C1A] = 0002 Sides. 7D55 8AF2 MOV DH,DL 7D57 8AE8 MOV CH,AL 7D59 C0CC02 * ror ah,02 7D5C 0ACC OR CL,AH 7D5E B80102 MOV AX,0201 ; Function 0201h is the INT 13 ; READ 01 sector from drive DL. 7D61 807E020E CMP BYTE PTR [BP+02],0E 7D65 7504 JNZ 7D6B 7D67 B442 MOV AH,42 ; Function 42h is an Extended ; INT 13 READ from Disk drive 7D69 8BF4 MOV SI,SP 7D6B 8A5624 MOV DL,[BP+24] ; [7C24] = 0 --> A:\ drive. 7D6E CD13 INT 13 7D70 61 * popa ; Pop Registers from Stack 7D71 61 * popa ; Pop Registers from Stack 7D72 720A JB 7D7E 7D74 40 INC AX 7D75 7501 JNZ 7D78 7D77 42 INC DX 7D78 035E0B ADD BX,[BP+0B] ; [7C0B]= 512 Bytes/Sector. 7D7B 49 DEC CX 7D7C 7577 JNZ 7DF5 7D7E C3 RET
7DF1 41 INC CX 7DF2 BB0007 MOV BX,0700 7DF5 60 * pusha ; Push Registers on Stack 7DF6 666A00 * push 0000 7DF9 E93BFF JMP 7D37
0 1 2 3 4 5 6 7 8 9 A B C D E F 7D7F 03 . 7D80 18 01 27 0D 0A 49 6E 76 61 6C 69 64 20 73 79 73 ..'..Invalid sys 7D90 74 65 6D 20 64 69 73 6B FF 0D 0A 44 69 73 6B 20 tem disk...Disk 7DA0 49 2F 4F 20 65 72 72 6F 72 FF 0D 0A 52 65 70 6C I/O error...Repl 7DB0 61 63 65 20 74 68 65 20 64 69 73 6B 2C 20 61 6E ace the disk, an 7DC0 64 20 74 68 65 6E 20 70 72 65 73 73 20 61 6E 79 d then press any 7DD0 20 6B 65 79 0D 0A 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 7F 01 SYSMSDOS SYS.. 7DF0 00 . 0 1 2 3 4 5 6 7 8 9 A B C D E F |
Revised: 29 April 2003.
Last Update: 27 April 2005 (27.04.2005);
Updated: 5 April 2009 (05.04.2009).
You can write to me using this:
online reply form.
(It opens in a new window.)
MBR and Boot Records Index
The Starman's Realm Index Page