Windows 95a Boot Sector


Abstract

This is a look at the Windows 95a boot sector as a companion to the discussion of the Windows 95b Boot Sector. The unassembled program code is shown and commented. The BIOS Parameter Block (BPB) for 16-bit FAT and the root directory structure are also examined.

Table of Contents


Introduction

This discussion focuses on the Windows 95a boot code. The boot sector is shown in Hex and ASCII view and the program code is unassembled and commented. The BIOS Parameter Block (BPB) is shown (for 16-bit FAT) as well as the structure of the root directory since these are pertinent to the boot code and were not shown in Windows 95b Boot Sector although the differences between the BPB for FAT16 and FAT32 were discussed.

This boot sector is from a PC which was originally formatted with WFWG 3.11 and then upgraded to Windows 95 using an early upgrade CD. This boot program may not be the same as one on a PC originally formatted with Windows 95. For previous versions of the boot code, up to DOS 6.22, see Hale's HIW series listed in the On Line References section, especially the page How It Works: DOS Floppy Disk Boot Sector. Hale's HIW series contain additional information not presented here. The references also include two web sources that also discuss the Windows 95 boot sector.

Disk Structure

This is a quick look at the disk structure to help visualize some of the nomenclature.

The first sector on the hard disk contains the MBR. The remaining sectors on this track are unused. Then follows the primary and extended partitions defined in the MBR partition table. The first sector of a primary partition is the boot sector while the first sector of an extended partition is a Partition Boot Record.

For DOS partitions, starting with the boot sector, there are the following areas:

Boot Sector, FAT1, FAT2, Root Directory, Data files and subdirectories
where the Root Directory has a fixed location and size on the hard disk as compared to FAT32 in Windows 95b and later where the size and location are variable.

Definitions

See PC Glossary for a list of definitions. Especially important is the use (or misuse) of MB and GB.

Go back to the Table of Contents.

Boot Record - Layout

Boot Record (bootable) - Hex view

OFFSET  0  1  2  3  4  5  6  7    8  9  A  B  C  D  E  F  0123456789ABCDEF
--------------------------------------------------------------------------
000000 EB 3E 90 4D 53 57 49 4E - 34 2E 30 00 02 20 01 00  ...MSWIN4.0.. ..
000010 02 00 02 00 00 F8 FF 00 - 3F 00 FF 00 3F 00 00 00  ........?...?...
000020 C3 DD 1F 00 80 00 29 F0 - 13 73 10 57 49 4E 5F 39  ......)..s.WIN_9
000030 35 20 20 20 20 20 46 41 - 54 31 36 20 20 20 F1 7D  5     FAT16   .}
000040 FA 33 C9 8E D1 BC FC 7B - 16 07 BD 78 00 C5 76 00  .3.....{...x..v.
000050 1E 56 16 55 BF 22 05 89 - 7E 00 89 4E 02 B1 0B FC  .V.U.".....N....
000060 F3 A4 06 1F BD 00 7C C6 - 45 FE 0F 8B 46 18 88 45  ......|.E...F..E
000070 F9 FB 38 66 24 7C 04 CD - 13 72 3C 8A 46 10 98 F7  ..8f$|...r..F...
000080 66 16 03 46 1C 13 56 1E - 03 46 0E 13 D1 50 52 89  f..F..V..F...PR.
000090 46 FC 89 56 FE B8 20 00 - 8B 76 11 F7 E6 8B 5E 0B  F..V.. ..v....^.
0000A0 03 C3 48 F7 F3 01 46 FC - 11 4E FE 5A 58 BB 00 07  ..H...F..N.ZX...
0000B0 8B FB B1 01 E8 94 00 72 - 47 38 2D 74 19 B1 0B 56  .......rG8-t...V
0000C0 8B 76 3E F3 A6 5E 74 4A - 4E 74 0B 03 F9 83 C7 15  .v....tJNt......
0000D0 3B FB 72 E5 EB D7 2B C9 - B8 D8 7D 87 46 3E 3C D8  ;.r...+...}.F...
0000E0 75 99 BE 80 7D AC 98 03 - F0 AC 84 C0 74 17 3C FF  u...}.......t...
0000F0 74 09 B4 0E BB 07 00 CD - 10 EB EE BE 83 7D EB E5  t............}..
000100 BE 81 7D EB E0 33 C0 CD - 16 5E 1F 8F 04 8F 44 02  ..}..3........D.
000110 CD 19 BE 82 7D 8B 7D 0F - 83 FF 02 72 C8 8B C7 48  ....}.}....r...H
000120 48 8A 4E 0D F7 E1 03 46 - FC 13 56 FE BB 00 07 53  H.N....F..V....S
000130 B1 04 E8 16 00 5B 72 C8 - 81 3F 4D 5A 75 A7 81 BF  .....[r..?MZu...
000140 00 02 42 4A 75 9F EA 00 - 02 70 00 50 52 51 91 92  ..BJu....p.PRQ..
000150 33 D2 F7 76 18 91 F7 76 - 18 42 87 CA F7 76 1A 8A  3..v...v.B...v..
000160 F2 8A 56 24 8A E8 D0 CC - D0 CC 0A CC B8 01 02 CD  ..V$............
000170 13 59 5A 58 72 09 40 75 - 01 42 03 5E 0B E2 CC C3  .YZXr..u.B......
000180 03 18 01 27 0D 0A 49 6E - 76 61 6C 69 64 20 73 79  ...'..Invalid sy
000190 73 74 65 6D 20 64 69 73 - 6B FF 0D 0A 44 69 73 6B  stem disk...Disk
0001A0 20 49 2F 4F 20 65 72 72 - 6F 72 FF 0D 0A 52 65 70   I/O error...Rep
0001B0 6C 61 63 65 20 74 68 65 - 20 64 69 73 6B 2C 20 61  lace the disk, a
0001C0 6E 64 20 74 68 65 6E 20 - 70 72 65 73 73 20 61 6E  nd then press an
0001D0 79 20 6B 65 79 0D 0A 00 - 49 4F 20 20 20 20 20 20  y key...IO
0001E0 53 59 53 4D 53 44 4F 53 - 20 20 20 53 59 53 80 01  SYSMSDOS   SYS..
0001F0 00 57 49 4E 42 4F 4F 54 - 20 53 59 53 00 00 55 AA  .WINBOOT SYS..U.

Go back to the Table of Contents.


BIOS Parameter Block (BPB)

The BPB contains information about the physical parameters of the current volume. Some sources include the OEM ID as part of the BPB while most others do not. This document does not include the OEM ID in the BPB. The BPB in this document is for a FAT16 volume running Windows 95a.

Bios Parameter Block (BPB) Fields for FAT16 Volumes

In the following table, numbers are followed by a d for decimal or an h for hex, while those not followed by a d or an h refer to the bytes in the order they are stored in the BPB. The first column labeled "Start of entry" refers to the start of the boot sector not the start of the BPB. The OEM ID field is not strictly part of the BPB but is included here for completeness.

BPB and EBPB Fields for FAT16 Volumes
Hex Offset from
Start of Entry

Length

Value

Description
03h8 bytesMSWIN4.0OEM ID (Windows 95 in this case)
0Bh2 bytes0002 = 0200h = 512d Number of bytes per sector
0Dh1 byte20h = 32d Number of sectors per cluster
0Eh2 bytes0100 = 0001h = 1d Number of sectors in reserved area
10h1 byte02Number of copies of FAT
11h2 bytes0002 = 200h = 512d Number of root directory entries (FAT12/FAT16 only)
13h2 bytes0000 = 0d Small Sectors
15h1 byteF8 DOS media descriptor - 0xF8 for hard disk
16h2 bytesFF00 = 00FFh = 255d Number of sectors per FAT (FAT12/FAT16 only)
18h2 bytes3F00 = 003Fh = 63d Number of sectors per track
1Ah2 bytesFF00 = 00FFh = 255d Number of heads (sides)
1Ch4 bytes0000003Fh = 63d Number of hidden sectors
20h4 bytes001FDDC3h = 2,088,387d Total Sectors if Small Sectors = 0
Extended BPB Fields for FAT16 Volumes
24h1 byte80hPhysical drive number
25h1 byte00h(Reserved)
26h1 byte29hSignature byte (29h)
27h4 bytesF0137310 = 107313F0h Volume serial number
2Bh11 bytesWIN_95 Volume label
36h8 bytesFAT16 File System Type

Go back to the Table of Contents.

Root Directory Structure

Both the root directory and subdirectories contain a list of 32-byte entries. The root directory is limited to 512 entries (using standard 8.3 byte entries) and has a fixed location (directly following the FAT sectors) while a subdirectory is not limited in size and can be located anywhere in the data area.

Structure of Directory Entries
(See notes below for coded words and bits)
Hex Offset from
Start of Entry
Length
in bytes

Description

Type
00h8FilenameASCII characters
08h3Filename extensionASCII characters
0Bh1AttributeCoded bits
0Ch10ReservedUnused in FAT12/FAT16
16h2TimeCoded Word
18h2DateCoded Word
1Ah2Starting cluster numberor 0 (see below)
1Ch4File sizeSize in bytes

Note that the Starting cluster number is the starting cluster number for the file or 0 for zero byte files and volume label entries.

Bit Fields of the Attribute Byte
Bit
Meaning
7654321 0
....... 1Read-only
......1 .Hidden
.....1. .System
....1.. .Volume Label
...1... .Subdirectory
..1.... .Archive
.1..... .Unused
1...... .Unused

Notes:

Boot Record - Program

Overview of Boot Program

Note that the boot partition in this example has been formatted using FAT16.

The MBR code loads the boot sector into memory location 0000:7C00 and uses a RET instruction to transfer execution to the boot sector code.

  1. Save address of Diskette Parameter Table (DPT) pointed to by INT 1Eh.
  2. Change INT 1E so that it will point to the altered DPT at 0000:0522.
  3. Copy DPT to 0000:0522.
  4. Alter the copy of the Diskette Parameter Table.
  5. Perform a disk reset if booting from a floppy disk.
  6. Determine LBA address of the root directory starting sector.
  7. Determine LBA address of first sector in the data area.
  8. Read each sector of the root directory (16 entries) into the data buffer, one at a time, and look for WINBOOT.SYS filename.
  9. If WINBOOT.SYS filename is not found, then read each sector of the root directory (16 entries) into the data buffer, one at a time, and look for IO.SYS filename.
  10. If WINBOOT.SYS or IO.SYS is found, then the first 4 sectors of the file are loaded into memory.
  11. Else error message "Invalid system disk" is displayed followed by the message "Replace the disk, and then press any key" and after a key is pressed the system will reboot.

Program notes

Go back to the Table of Contents.

Disassembly of Boot Program

The following boot program was on Cylinder 0, Head 1, Sector 1 of a PC running Windows 95a which was upgraded from WFWG 3.11 using an early upgrade CD.

Numbers enclosed in {} brackets represent actual numbers from the BPB.

The first 3 bytes of the boot sector are JMP and NOP instructions.

1174:7C00 EB3E        JMP     7C40            jmp over BPB to START
1174:7C02 90          NOP                     No Op instruction (do nothing)

The BPB (BIOS Parameter Block) is contained in Offsets 7C03 to 7C3D.
See structure and values above.

Offsets 7C3E and 7C3F contain F1 7D = 7DF1h (address of text WINBOOT SYS in 
   message area, used in FIND_SYS: and FIND_IO:)
   [7DD8] = IO      SYS
   [7DF1] = WINBOOT SYS


     START:           START OF BOOT SECTOR PROGRAM

0000:7C40 FA          CLI                     Clear interrupts (turn off)
0000:7C41 33C9        XOR     CX,CX           Set CX (Count Register) to zero
0000:7C43 8ED1        MOV     SS,CX           Set SS (Stack Segment) to zero
0000:7C45 BCFC7B      MOV     SP,7BFC         Set SP (Stack Ptr) to 7BFC
0000:7C48 16          PUSH    SS              Also set ES (Extra Segment Register)
0000:7C49 07          POP     ES                 to zero


                      Copy the address that the INT 1E vector points to 
                         into the DS:SI registers.

0000:7C4A BD7800      MOV     BP,0078         Set BP = address of INT 1E
0000:7C4D C57600      LDS     SI,[BP+00]      Set DS:SI = address of DPT
0000:7C50 1E          PUSH    DS              Save DS:SI --
0000:7C51 56          PUSH    SI                 original address of DPT
0000:7C52 16          PUSH    SS              Save SS:BP --
0000:7C53 55          PUSH    BP                 address of INT 1E
0000:7C54 BF2205      MOV     DI,0522         ES:DI = new address of DPT at 0000:0522

                      Change INT 1E so that it points to the altered 
                         Diskette parameter table at 0000:0522.

0000:7C57 897E00      MOV     [BP+00],DI      Change INT 1E offset to 0522
0000:7C5A 894E02      MOV     [BP+02],CX      Change INT 1E segment to 0000

                      Copy the diskette parameter table to 0000:0522.

0000:7C5D B10B        MOV     CL,0B           Set CX (Count register) to 11d
0000:7C5F FC          CLD                     Clear Direction Flag (set DF=0)
0000:7C60 F3          REPZ                    Copy the diskette parameter table (11 bytes)
0000:7C61 A4          MOVSB                      from DS:SI to ES:DI
0000:7C62 06          PUSH    ES              Also set DS (Data Segment)
0000:7C63 1F          POP     DS                 to zero
0000:7C64 BD007C      MOV     BP,7C00         Set BP (Base Pointer) to 7C00

                      Alter some of the diskette parameter table data.

0000:7C67 C645FE0F    MOV     BYTE PTR [DI-02],0F   Set Diskette settling time = 15ms
0000:7C6B 8B4618      MOV     AX,[BP+18]               and Sectors per track from BPB {63d}
0000:7C6E 8845F9      MOV     [DI-07],AL               and save in new table
0000:7C71 FB          STI                           Turn interrupts on

                      Perform a disk reset if booting from a floppy disk
                         Floppy drives (00-7F), hard drives (80h - FFh)

0000:7C72 386624      CMP     [BP+24],AH      Check Physical drive number{80h}, AH=0
0000:7C75 7C04        JL      7C7B               if hard drive (>80h), jmp to ROOT_DIR:
0000:7C77 CD13        INT     13              Do disk reset (Function AH = 0)
0000:7C79 723C        JB      7CB7            If Error, jmp to INT13_OK:

     ROOT_DIR:        Determine LBA address of the root directory starting sector.


0000:7C7B 8A4610      MOV     AL,[BP+10]      Number of copies of FAT {2}
0000:7C7E 98          CBW                       Convert 8-bit number (AL) to 16-bit (AX)
0000:7C7F F76616      MUL     WORD PTR [BP+16]    Num FATs * Sectors per FAT
0000:7C82 03461C      ADD     AX,[BP+1C]        Add num of Hidden Sectors
0000:7C85 13561E      ADC     DX,[BP+1E]           with result in DX,AX
0000:7C88 03460E      ADD     AX,[BP+0E]      Add num of Reserved Sectors
0000:7C8B 13D1        ADC     DX,CX              with result in DX,AX (CX=0)
0000:7C8D 50          PUSH    AX              Save start address of root dir
0000:7C8E 52          PUSH    DX                 (as LBA in DX,AX) on stack.
0000:7C8F 8946FC      MOV     [BP-04],AX      Save start address of root dir
0000:7C92 8956FE      MOV     [BP-02],DX         (as LBA in DX,AX)

                      Determine LBA address of first sector in the data area.

0000:7C95 B82000      MOV     AX,0020         AX = Size of a dir entry (32 bytes)
0000:7C98 8B7611      MOV     SI,[BP+11]      SI = Number of root dir entries
0000:7C9B F7E6        MUL     SI              Put total size of Root Dir in DX,AX
0000:7C9D 8B5E0B      MOV     BX,[BP+0B]      BX = Bytes per Sector
0000:7CA0 03C3        ADD     AX,BX           Compute number of sectors in
0000:7CA2 48          DEC     AX                 Root Dir, rounded up to
0000:7CA3 F7F3        DIV     BX                 an integer.
0000:7CA5 0146FC      ADD     [BP-04],AX      Add to start addr of root dir (as LBA)
0000:7CA8 114EFE      ADC     [BP-02],CX         to give first sector in the data area
0000:7CAB 5A          POP     DX              Restore start address of root dir
0000:7CAC 58          POP     AX                 (as LBA in DX,AX) from stack.

     READ_DIR:        Read next sector of root directory (16 entries) into buffer

0000:7CAD BB0007      MOV     BX,0700         Address to read into (data buffer at ES:BX)
0000:7CB0 8BFB        MOV     DI,BX           Store READ address offset in DI (ES = 0)
0000:7CB2 B101        MOV     CL,01           Count parameter for READ_LOOP:
0000:7CB4 E89400      CALL    7D4B            Call READ_LOOP: (Read next sector of root dir)

     INT13_OK:        Check for INT 13 error and hang system if error

0000:7CB7 7247        JB      7D00            If INT 13 error jmp to IO_ERROR:

     FIND_SYS:        Look for WINBOOT.SYS and if not found, IO.SYS in root directory

0000:7CB9 382D        CMP     [DI],CH         If last entry in root dir (first byte is 0),
0000:7CBB 7419        JZ      7CD6               jmp to FIND_IO:
0000:7CBD B10B        MOV     CL,0B           Set CX (Count) to 11d (filename length)
0000:7CBF 56          PUSH    SI              Save SI (Number of root dir entries)
0000:7CC0 8B763E      MOV     SI,[BP+3E]      Set SI to address of filename (7DF1 or 7DD8)
0000:7CC3 F3          REPZ                    Compare filenames, 11 bytes starting at
0000:7CC4 A6          CMPSB                      [SI] and [DI], CX=0 and ZF=1 if same
0000:7CC5 5E          POP     SI              Restore SI (Number of root dir entries)
0000:7CC6 744A        JZ      7D12            If correct file name, jmp to LOAD_SYS:
0000:7CC8 4E          DEC     SI              Counting down number of root dir entries
0000:7CC9 740B        JZ      7CD6            If SI = 0 (no more entries), jmp to FIND_IO:
0000:7CCB 03F9        ADD     DI,CX           Set DI to address of next root dir entry
0000:7CCD 83C715      ADD     DI,+15             (note that DI+CX remains constant in CMPSB)
0000:7CD0 3BFB        CMP     DI,BX           If DI < BX (if DI still points to read data),
0000:7CD2 72E5        JB      7CB9               jmp to FIND_SYS:
0000:7CD4 EBD7        JMP     7CAD            Else, jmp to READ_DIR: (Read next root dir sector)

     FIND_IO:         Set [BP+3E] to point to IO.SYS filename in message area

0000:7CD6 2BC9        SUB     CX,CX           Set CX to 0 (for ROOT_DIR:)
0000:7CD8 B8D87D      MOV     AX,7DD8         Set AX to 7DD8
0000:7CDB 87463E      XCHG    AX,[BP+3E]      Set AX to 7DF1 if first call to FIND_IO
0000:7CDE 3CD8        CMP     AL,D8           If AL <> D8 (first time through FIND_IO)
0000:7CE0 7599        JNZ     7C7B               then jmp to ROOT_DIR:
0000:7CE2 BE807D      MOV     SI,7D80         Else set SI to 7D80 (message offset)

     GET_MSG:         Compute message address (SI + [SI] + LODSB increments SI).

0000:7CE5 AC          LODSB                   get message offset from [SI] and put in AL
0000:7CE6 98          CBW                     extend sign bit in AL to AX
0000:7CE7 03F0        ADD     SI,AX           add offset to SI (LODSB also increments SI)

     DISPLAY_MSG:     Display message loop (SI now points to message).

0000:7CE9 AC          LODSB                   get char of message from [SI] and put in AL
0000:7CEA 84C0        TEST    AL,AL           is AL = 0?
0000:7CEC 7417        JZ      7D05               yes - jmp to ANY_KEY: (reboot)
0000:7CEE 3CFF        CMP     AL,FF           is AL = FF?
0000:7CF0 7409        JZ      7CFB               yes - jmp to ERROR_MSG:
0000:7CF2 B40E        MOV     AH,0E           output 1 char of message
0000:7CF4 BB0700      MOV     BX,0007            with screen attributes
0000:7CF7 CD10        INT     10                 to the display
0000:7CF9 EBEE        JMP     7CE9            jmp to DISPLAY_MSG (next char of message)

     ERROR_MSG:       For message "Replace the disk, and then press any key" (followed by 00h)

0000:7CFB BE837D      MOV     SI,7D83         [SI] = 27h  ([7D83h+27h+1]=[7DAB])
0000:7CFE EBE5        JMP     7CE5            jmp to GET_MSG

     IO_ERROR:        For message "Disk I/O error" (followed by FFh)

0000:7D00 BE817D      MOV     SI,7D81         [SI] = 18h  ([7D81h+18h+1]=[7D9A])
0000:7D03 EBE0        JMP     7CE5            jmp to GET_MSG

     ANY_KEY:         Wait for keyboard response and reboot.

0000:7D05 33C0        XOR     AX,AX           set AX (Accumulator) to zero
0000:7D07 CD16        INT     16              read Keyboard input (AH=0)
0000:7D09 5E          POP     SI              restore SI
0000:7D0A 1F          POP     DS              restore DS
0000:7D0B 8F04        POP     [SI]
0000:7D0D 8F4402      POP     [SI+02]
0000:7D10 CD19        INT     19              Bootstrap Loader (load MBR)

     LOAD_SYS:        Load System file into memory and jump to offset 200 in the file

0000:7D12 BE827D      MOV     SI,7D82         For message = "Invalid system disk"
0000:7D15 8B7D0F      MOV     DI,[DI+0F]      Set DI to Starting cluster # in root dir entry
0000:7D18 83FF02      CMP     DI,+02          If DI < 2 (less than first cluster), then
0000:7D1B 72C8        JB      7CE5               jmp to GET_MSG (Invalid system disk)
0000:7D1D 8BC7        MOV     AX,DI           Set AX to Starting cluster #
0000:7D1F 48          DEC     AX              Since cluster numbers start at 2 in the
0000:7D20 48          DEC     AX                 data area, subtract 2
0000:7D21 8A4E0D      MOV     CL,[BP+0D]      Set CL to # of sectors per cluster
0000:7D24 F7E1        MUL     CX              Compute # of sectors to start of file
0000:7D26 0346FC      ADD     AX,[BP-04]         by adding starting sector in data area to
0000:7D29 1356FE      ADC     DX,[BP-02]         LBA address of first sector in the data area
0000:7D2C BB0007      MOV     BX,0700         Address to read into (data buffer at ES:BX)
0000:7D2F 53          PUSH    BX              Save READ buffer offset (ES = 0)
0000:7D30 B104        MOV     CL,04           Count parameter for READ_LOOP: (4 sectors)
0000:7D32 E81600      CALL    7D4B            Call READ_LOOP: (INT 13 READ of file)
0000:7D35 5B          POP     BX              Restore READ buffer offset (ES = 0)
0000:7D36 72C8        JB      7D00               If Int 13 error, jmp to IO_ERROR:
0000:7D38 813F4D5A    CMP     WORD PTR [BX],5A4D    If first 2 bytes of file <> MZ, then
0000:7D3C 75A7        JNZ     7CE5                     jmp to GET_MSG: (Invalid system disk)
0000:7D3E 81BF0002424A CMP    WORD PTR [BX+0200],4A42  If 1st 2 bytes of 2nd sector <> BJ, then
0000:7D44 759F        JNZ     7CE5                        jmp to GET_MSG: (Invalid.... )
0000:7D46 EA00027000  JMP     0070:0200       File OK, continue at offset 200 of the file

     READ_LOOP:       Convert LBA address in DX,AX to CHS for INT 13 READ and read sectors
                      Save AX in CX, put DX in AX and set DX to 0 for CHS computation.
                          DX = high Word for Starting Sector to read.
                          AX = low Word for Starting Sector to read.

0000:7D4B 50          PUSH    AX              Save AX value on stack
0000:7D4C 52          PUSH    DX              Save DX value on stack
0000:7D4D 51          PUSH    CX              Save CX value on stack (01)
0000:7D4E 91          XCHG    CX,AX           Save AX into CX
0000:7D4F 92          XCHG    DX,AX           Save DX into AX
0000:7D50 33D2        XOR     DX,DX           Set DX (Data Register) to zero

                      Convert start address of root dir from LBA to CHS

0000:7D52 F77618      DIV     WORD PTR [BP+18]    Divide start address of root dir
0000:7D55 91          XCHG    CX,AX                  by Sectors per Track and put
0000:7D56 F77618      DIV     WORD PTR [BP+18]       result in CX,AX (LBA to # of tracks)
0000:7D59 42          INC     DX                  Add 1 to Remainder (# of sectors)
0000:7D5A 87CA        XCHG    CX,DX               # of tracks in DX,AX; Sector # in CX
0000:7D5C F7761A      DIV     WORD PTR [BP+1A]   Compute Cylinder #, put in AX

                      Set up registers and perform standard INT 13 CHS READ

0000:7D5F 8AF2        MOV     DH,DL              Put Head # in DH
0000:7D61 8A5624      MOV     DL,[BP+24]      DL = Drive number for INT 13
0000:7D64 8AE8        MOV     CH,AL           CH = low 8 bits of Cyl # for INT 13
0000:7D66 D0CC        ROR     AH,1            Put high 2 bits of Cyl # into
0000:7D68 D0CC        ROR     AH,1               bits 7,6 of AH and combine with
0000:7D6A 0ACC        OR      CL,AH              Sector # in bits 5-0 of CL.
0000:7D6C B80102      MOV     AX,0201         Read one sector from disk
0000:7D6F CD13        INT     13                 using standard INT 13 CHS READ
0000:7D71 59          POP     CX              Restore CX (loop count)
0000:7D72 5A          POP     DX              Restore start address of root dir
0000:7D73 58          POP     AX                 (as LBA in DX,AX) from stack.
0000:7D74 7209        JB      7D7F            If READ error, return from CALL via 0000:7D7F

                      Increment registers for next INT 13 CHS READ

0000:7D76 40          INC     AX              Increment AX
0000:7D77 7501        JNZ     7D7A            If no carry out of AX, skip next instruction
0000:7D79 42          INC     DX              Increment DX if carry out of AX
0000:7D7A 035E0B      ADD     BX,[BP+0B]      Increase BX by one sector (512 bytes)
0000:7D7D E2CC        LOOP    7D4B            Loop (to READ_LOOP:) CX number of times
0000:7D7F C3          RET                     Return from CALL at 7CB4


Locations 7D80, through 7D83 contain offset values used in GET_MSG
0000:7D80 03    For message "Invalid system disk" in FIND_IO:
0000:7D81 18    For message "Disk I/O error" in IO_ERROR:
0000:7D82 01    For message "Invalid system disk" in LOAD_SYS:
0000:7D83 27    For message "Replace the disk, and then press any key" in ERROR_MSG:


Messages here.

0000:7D80 .. .. .. .. 0D 0A 49 6E - 76 61 6C 69 64 20 73 79     ...Invalid sy
0000:7D90 73 74 65 6D 20 64 69 73 - 6B FF 0D 0A 44 69 73 6B  stem disk...Disk
0000:7DA0 20 49 2F 4F 20 65 72 72 - 6F 72 FF 0D 0A 52 65 70   I/O error...Rep
0000:7DB0 6C 61 63 65 20 74 68 65 - 20 64 69 73 6B 2C 20 61  lace the disk, a
0000:7DC0 6E 64 20 74 68 65 6E 20 - 70 72 65 73 73 20 61 6E  nd then press an
0000:7DD0 79 20 6B 65 79 0D 0A 00 - .. .. .. .. .. .. .. ..  y key...

MS DOS hidden file names

0000:7DD0 .. .. .. .. .. .. .. .. - 49 4F 20 20 20 20 20 20          IO
0000:7DE0 53 59 53 4D 53 44 4F 53 - 20 20 20 53 59 53 80 01  SYSMSDOS   SYS..
0000:7DF0 00 57 49 4E 42 4F 4F 54 - 20 53 59 53 00 00        .WINBOOT SYS..

The last two bytes contain a 55AAH signature.

0000:7DF0 .. .. .. .. .. .. .. .. - .. .. .. .. .. .. 55 AA                U.

Go back to the Table of Contents.

References

On Line References

For other commented unassembled Windows 95a boot sector program code see (both contain identical program code to the present document):

For comparison with an older version of the boot sector see:

The Microsoft article "Disk Sectors Critical to Startup" contains information on both the MBR and the boot sector including details on the BPB for both FAT16 and FAT32 volumes. This article is part of Chapter 32 "Disk Concepts and Troubleshooting" in the Microsoft Windows 2000 Professional Resource Kit. Thanks to the Starman and Fons Van Assche for keeping me updated on Microsoft's changing links. (updated 7/2/03)

Other pertinent Microsoft articles.

Also see FAT Boot Sector by Alex Verstak for a more detailed description of the boot sector BPB fields for FAT32, FAT16, and FAT12 file systems.

For more information on Interrupt 13 as well as other interrupts:

Opcodes for the x86 processors can be found in the Intel Architecture Software Developer's Manual, Volume 2: Instruction Set Reference Manual which is part of a three-volume set that describes the architecture and programming environment of all Intel Architecture processors and can be downloaded as a PDF file.

Other Intel documents can be found through Intel's Literature Center

Additional sources of information:

Other References

Go back to the Table of Contents.


MBR/Boot Index

Home Page

This page was created on 22 December 2000, last updated on 2 September 2003.