An Examination of the
MSWIN4.1 OS Boot Record
[  Embedded  in  Microsoft's  SYS.COM  and
FORMAT.COM Programs (and some other
files as well*)
for Windows™ 95B (OSR2),
Windows
98/98SE and Windows ME  ]

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






The MSWIN4.1 BIOS Parameter Block

    "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
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!
NOTE: If you compare this entry to a Windows™ 2000/XP FAT32 Boot Record for an Extended partition that contains an OS (not just data), you may find that volume maintains the true "Number of Hidden Sectors" in front of it (which wouldn't all be hidden in that case!); not just to the beginning of the Extended partition, but to the first sector on the whole physical drive! Thus, it may be possible to boot Windows™ 9x/Me from within an Extended partition, if you manually edit this entry.

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
24h Double Word 00001788 6,024  Sectors per FAT (FAT32)
28h Word 0000 0  Active FAT
      Bits 0-3: Zero-based number of active FAT. Only valid if mirroring is disabled.
    Bits 4-6: Reserved.
        Bit 7: 0 means the FAT is mirrored at runtime into all FATs. 1 means only one
                 FAT is active; it is the one referenced in bits 0-3.
  Bits 8-15: Reserved.
2Ah Word 0000 0.0  File System Version
2Ch Double Word 00000002 2  First Cluster in the Root
 Directory
Reference    " This is set to the cluster number of the first cluster of the root directory, usually 2 but not required to be 2. NOTE: Disk utilities that change the location of the root directory should make every effort to place the first cluster of the root directory in the first non-bad cluster on the drive (i.e., in cluster 2, unless it’s marked bad). This is specified so that disk repair utilities can easily find the root directory if this field accidentally gets zeroed."
30h Word 0001 1  File System Info Sector ;
 counting from Logical Sector 0
Reference    " Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1. NOTE: There will be a copy of the FSINFO structure in BackupBoot, but only the copy pointed to by this field will be kept up to date (i.e., both the primary and backup boot record will point to the same FSINFO sector)."
[ Essentially it means this: The data in the backup FSINFO sector is never updated. ]
32h Word 0006 6  Backup Boot Sector ;
 counting from Logical Sector 0
Reference    " If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6. No value other than 6 is recommended. "
34h 12 bytes Each byte: 00 N/A  Reserved (Not Used)
Reference    " Reserved for future expansion. Code that formats FAT32 volumes should always set all of the bytes of this field to 0."
40h Byte 80 128 (First HD)  Physical Disk Drive ID
41h Byte 00 N/A  ( Reserved for NT )
42h Byte 29 Since DOS V4  Extended Boot Signature; a 29h indicates that the following three fields should be present.
43h Double Word B9372FAC B937-2FAC  Volume Serial Number (OS uses date/time to generate this when the volume is formatted).
47h 11 Bytes ( ASCII data ) "MY_C_DRIVE "  Volume Label ( Max. of
 Eleven characters )
52h 8 Bytes ( ASCII data ) "FAT32    "  File System ID
Reference    " NOTE: Many people think that the string in this field has something to do with the determination of what type of FAT (FAT12, FAT16, or FAT32) that the volume has. This is not true. You will note from its name that this field is not actually part of the BPB. This string is informational only and is not used by Microsoft file system drivers to determine FAT type because it is frequently not set correctly or is not present. See the FAT Type Determination section of this document. This string should be set based on the FAT type though, because some non-Microsoft FAT file system drivers do look at it."   [ For Microsoft, The FAT type is simply determined by the count of clusters on the volume; and nothing else. ]

 

FSInfo Sector Data

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."






An Examination of the Assembly Code



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.


Free Tools

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!!



Updated: June 7, 2007. (2007.06.07)
Last Update: May 8, 2013. (2013.05.08)

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