This page examines the MBR code used in IBM's FDISK.COM utility for IBM® Personal Computer DOS 2.00 (1983) and all versions after that (including 2.10, 3.00, 3.10, 3.20 and 3.21) until the release of IBM® Personal Computer DOS 3.30 in which a few changes were made to the original MBR code that finally became what The Starman's Realm refers to as "The Standard MBR". |
Other IBM® and Microsoft® MBR pages:
The Standard MBR created by IBM/MS-DOS 3.30 through Windows
95
The MBR created by MS-Windows 95B/98 and ME's FDISK
The MBR created by MS-Windows 2000/XP
And OS Volume Boot Record pages:
An Examination of the MS-DOS 5.0 Floppy Disk Boot Record
An Examination of the MS-Windows 95B/98 OS Boot Record (MSWIN4.1)
An Examination of the MS-Windows 2000/XP OS Boot Record (NTFS)
This page examines the code that was written to the first sector of a Hard Drive when they were partitioned by FDISK.COM from any IBM® Personal Computer DOS 2.00 or higher until the realease of IBM® Personal Computer DOS 3.30; at a time when the computer Memories we have today would be larger than those Hard Drives.
During that early period in the history of DOS, the FDISK.COM program for
most Microsoft® Disk Operating Systems had to be rewritten for all of
their OEM clients, because the OEM computers were often very different than the IBM®
machines. It took quite some time for true "clones" to become a
reality in the computing industry. It seemed as if every electronics company wanted to get into the business of making computers! When some
companies finally put all their effort into making "IBM® clone" boxes, most of the other name brand computers (with rare
exceptions, such as Apple) either did the same, or stopped making comptuers. The point being: Each Microsoft® DOS until version 3.30, must have its MBR code examined to see how it
compares to the code on this page.
NOTE: This code has the name of an IBM employee embedded in it. The implication being that until much later in the history of
computers, MBR code was actually a product of IBM; not Microsoft.
Here's a disk editor view of the MBR code as it was stored on a hard disk's first sector; that's Absolute (or Physical) Sector
0 or CHS 0,0,1. (See Examination of the Code below to find out where this data ended up in the Memory of a computer.)
Absolute Sector 0 (Cylinder 0, Head 0, Sector 1) 0 1 2 3 4 5 6 7 8 9 A B C D E F 0000 FA 33 C0 8E D0 BC 00 7C 8B F4 50 07 50 1F FB FC .3.....|..P.P... 0010 BF 00 06 B9 00 01 F3 A5 EA 1D 06 00 00 BE BE 07 ................ 0020 B3 04 80 3C 80 74 0E 82 3C 00 75 1C 83 C6 10 FE ...<.t..<.u..... 0030 CB 75 EF CD 18 8B 14 8B 4C 02 8B EE 83 C6 10 FE .u......L....... 0040 CB 74 1B 82 3C 00 74 F4 BE 8B 06 32 ED AC 8A C8 .t..<.t....2.... 0050 AC 56 BB 07 00 B4 0E CD 10 5E E2 F4 EB FE BF 05 .V......^....... 0060 00 BB 00 7C B8 01 02 57 CD 13 5F 73 0C 33 C0 CD ..|...W.._s.3... 0070 13 4F 75 ED BE A3 06 EB D2 BE C2 06 81 3E FE 7D .Ou..........>.} 0080 55 AA 75 C7 8B F5 EA 00 7C 00 00 17 49 6E 76 61 U.u.....|...Inva 0090 6C 69 64 20 70 61 72 74 69 74 69 6F 6E 20 74 61 lid partition ta 00A0 62 6C 65 1E 45 72 72 6F 72 20 6C 6F 61 64 69 6E ble.Error loadin 00B0 67 20 6F 70 65 72 61 74 69 6E 67 20 73 79 73 74 g operating syst 00C0 65 6D 18 4D 69 73 73 69 6E 67 20 6F 70 65 72 61 em.Missing opera 00D0 74 69 6E 67 20 73 79 73 74 65 6D 41 75 74 68 6F ting systemAutho 00E0 72 20 2D 20 44 61 76 69 64 20 4C 69 74 74 6F 6E r - David Litton 00F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 01A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 01B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 01 ................ 01C0 01 00 0B 7F BF FD 3F 00 00 00 C1 40 5E 00 00 00 ......?....@^... 01D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 01E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 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 first 139 bytes (00h through 8Ah) of the 512-byte sector are executable code[1], the next 80 bytes (8Bh through DAh) containerror messages[2] which are immediately followed by the phrase: "Author - David Litton"[3] (which was removed from the MBR for DOS 3.30). The last 66 bytes of this sector contain the 64-byte Partition Table (1BEh through 1FDh); data in the Table area will depend upon the size, structure and file systems on each hard disk. The sector ends with the Word-sized signature ID of AA55h (often called the sector's Magic number; On Intel CPU systems, hex Words are stored with the Low-byte first and the High-byte last). The remaining 206 bytes (from 0F0h to 1BDh) are all padding which FDISK fills with 00h bytes!
After executing the POST (Power-On Self Test), the BIOS code loads this sector into memory at 0000:7C00 then executes it by carrying out a simple jump instruction to the copied code: JMP 0000:7C00. Unlike an OS boot sector though, this code must first copy itself to 0000:0600. This is necessary because the MBR code will later load the Boot Sector of the Active Partition into the same area of memory that it was first loaded into!
You can learn a great deal about the instructions used here by obtaining the x86 Opcode Windows Help file and Ralf Brown's Interrupt List from my Intro to Assembly page. Here's a disassembled copy of the code (; with comments) after being loaded into memory by the BIOS at 0000:7C00 ( the 0000: Segment notation has been dropped from all the Memory locations listed below):
The code below that's hightlighted with a green background was retained without any changes in DOS versions 3.30 and beyond. The lines with a yellow background contain at least one byte that's different from the Standard MBR code.
When the MBR code for DOS 3.30 was released, the 'F3' byte that you see above (at location 7C16) was changed to an 'F2' for some odd reason; remaining that way until it was finally changed back to an 'F3' for Microsoft's FAT32 MBR. Since use of the 'F2' machine code byte for carrying out this instruction is at best 'undocumented' [see here for all the details], we can't help but wonder if changing this byte was due to an error in whatever Assembler the programmer(s) were using, or in fact something they actually intended to do.
These next two sections of code are almost exactly the same as
that used by the Standard MBR:
; This next bit of code tries to find an entry in the partition table ; that indicates at least one of them is ACTIVE (i.e., bootable). The ; first byte of a partition entry is used as the indicator: If it's ; an 80h, yes; if 00 then no it's not bootable. If none of the four ; possible partitions is active, then an error message is displayed. 061D BEBE07 MOV SI,07BE ; Location of first entry ; in the partition table. 0620 B304 MOV BL,04 ; Maximum of 4 entries 0622 803C80 CMP BYTE PTR [SI],80 ; Is this one bootable? 0625 740E JZ 0635 ; Yes, jump to next test! 0627 823C00 CMP BYTE PTR [SI],00 ; No; is it a 00? If not, it's 062A 751C JNZ 0648 ; an Invalid partition table. 062C 83C610 ADD SI,+10 ; Checking the next entry... ; (10h = 16 bytes per entry) 062F FECB DEC BL ; SUB 1 from Entry counter. 0631 75EF JNZ 0622 ; Have all entries been tested? 0633 CD18 INT 18 ; Yes, and NONE of them were ; bootable, so start... ; ROM-BASIC (only available on ; some IBM machines!) Many BIOS ; simply display "PRESS A ; KEY TO REBOOT" when an ; Interrupt 18h is executed. ; We found an Active partition, so all the other entries are checked ; for being non-bootable (first byte = 0x00), or there's an error! ; (Only one entry in the Partition Table can be marked as 'Active.') |
The only difference above is in the use of an alternate machine code byte (the 82h at location 0627h changed to an 80h for DOS 3.30+) which was also repeated at 0643h (see below). Yet the first occurance of the "CMP BYTE PTR [SI],xx" instruction at 0622h was already using an 80h byte. The use of different machine code bytes for the same instructions are often the result of an Assembler program rather than a human decision; whereas making them all the same in DOS 3.30 probably was due to a programmer's intervention.
Apart from the alternate x86 machine code byte mentioned above, the only other difference is the jump length at 0641h being 1 byte longer due to an extra instruction further down in the code.
; Before doing so, we load the Head, Drive, Cylinder and Sector data ; into DX and CX for use by the DOS Interrupt 13 commands later. 0635 8B14 MOV DX,[SI] ; Drive -> DL / Head -> DH ; For the standard MBR code, ; DL will always be 80h; which ; means ONLY the first drive ; can be bootable! [ This part ; of the code is often changed ; by MBR replacements! ] 0637 8B4C02 MOV CX,[SI+02] ; Sector -> CL / Cylinder -> CH 063A 8BEE MOV BP,SI ; Save offset of active entry 063C 83C610 ADD SI,+10 ; Do next entry 063F FECB DEC BL ; Is this the last entry? 0641 741B JZ 065E ; -> Jump to Boot-routine! 0643 823C00 CMP BYTE PTR [SI],00 ; Non-bootable entry? 0646 74F4 JZ 063C ; Yes, check the next entry |
This next section is used to display messages. This is where most of the differences
occur! Looking at the error messages in the disk editor view above, you'll see three bolded hex bytes which tell
the code below how many bytes to display on the screen. For the DOS 3.30 MBR, these were all replaced by 00 bytes which were moved to
the end of each string. The code in DOS 3.30+ simply looks for the zero bytes to tell it when to stop displaying characters.
; If there's an error, then this next routine displays the message that ; SI points to. After printing the pre-determined number of bytes, the ; program 'locks up' by going into an infinite loop (at 065B): 0648 BE8B06 MOV SI,068B ; -> 17h + "Invalid partition table" |
064B 32ED XOR CH,CH ; Zero-out CH register |
064D AC LODSB ; Load byte at [SI] into AL ... ; and increment the SI value. |
064E 8AC8 MOV CL,AL ; Move "Number of characters to ; display" into CX register. 0650 AC LODSB ; Load character byte at [SI] into ; AL. (inc. SI -> don't care). |
0651 56 PUSH SI ; Store string pointer on stack. 0652 BB0700 MOV BX,0007 ; Use Function 0E (Write Text) of 0655 B40E MOV AH,0E ; DOS Interrupt 10 to send the 0657 CD10 INT 10 ; character in AL to the screen. 0659 5E POP SI |
065A E2F4 LOOP 0650 ; Loop through display routine for ; for as many times as the number ; in the CX register (forget SI). |
065C EBFE JMP 065C ; Infinite Loop. You must ; power-down or Reboot! |
Here's another section that's almost identical to that used by the Standard MBR. Only the byte at 0678h had to be changed to correct for a difference in offsets.
; Now we can load the first sector of the Active Partition (on most drives ; this would be Absolute Sector 63 for the first or only partition of your ; Hard Drive. Absolute Sectors 2 thru 62 are normally empty, unless you've ; installed a large MBR replacement, disk translation software for a very ; large HD or some kind of multi-OS or security/encryption boot code). ; ; The first two words of the partition entry are the drive/head ; and the sector/cylinder numbers of the first partition sector. ; This data is in the format required by the INT 13 calls below. 065E BF0500 MOV DI,0005 ; Retry 5 times (if necessary)... 0661 BB007C MOV BX,7C00 ; Load OS Boot Sector to 0000:7C00 0664 B80102 MOV AX,0201 ; Function 02h; read 1 sector. 0667 57 PUSH DI 0668 CD13 INT 13 066A 5F POP DI 066B 730C JNB 0679 ; Carry Flag set ? 066D 33C0 XOR AX,AX ; Yes, so we had an error! Must 066F CD13 INT 13 ; ...reset drive (Function 00h) 0671 4F DEC DI ; Decrement counter and 0672 75ED JNZ 0661 ; try again... 0674 BEA306 MOV SI,06A3 ; Or, declare: "Error loading 0677 EBD2 JMP 064B ; operating system" ; The section of code above is often changed by MBR replacements that ; will tell you if it ever takes more than ONCE to try loading the OS ; Boot code! Surely you'd want to know this wouldn't you?! ; This old code was obviously made in the days when hard drives, memory ; chips and the boot process itself may have been quite unreliable. |
In this last section of code, the longest instruction (at 067Ch) was split into two pieces for DOS 3.30+ by replacing the WORD for the memory location 7DFEh with [DI] to accomplish exactly the same thing (compare Standard MBR code here).
; Once a boot sector for the Active Partition has been loaded into memory,
; it must be checked to see if it is valid. This is accomplished by simply
; checking the last word of the sector; it must be the hex number 0xAA55.
0679 BEC206 MOV SI,06C2 ; -> 18h + "Missing operating system"
; Point to last Word in the sector
; ... it should be: AA55 Hex.
067C 813EFE7D55AA CMP WORD PTR [7DFE],AA55
; Is it? ('Signature' check)
0682 75C7 JNZ 064B ; If not, display Error Message
; and 'lock-up' system.
0684 8BF5 MOV SI,BP ; SI=BP -> Both are equal to...
; offset of Active Partition entry
; which is used by OS Boot code.
0686 EA007C0000 JMP 0000:7C00 ; Jump to OS Boot Sector code
; and continue booting-up!
|
Location of Error Messages in Memory
068B 17 49 6E 76 61 .Inva 0690 6C 69 64 20 70 61 72 74 69 74 69 6F 6E 20 74 61 lid partition ta 06A0 62 6C 65 1E 45 72 72 6F 72 20 6C 6F 61 64 69 6E ble.Error loadin 06B0 67 20 6F 70 65 72 61 74 69 6E 67 20 73 79 73 74 g operating syst 06C0 65 6D 18 4D 69 73 73 69 6E 67 20 6F 70 65 72 61 em.Missing opera 06D0 74 69 6E 67 20 73 79 73 74 65 6D ting system |
1[Return to Text] The 16 bolded blue bytes in the code section (the first one being F3; in the Disk Editor View above) are the bytes which were changed when this MBR took its final form in the release of DOS 3.30; turning it into what we're calling the Standard MBR.
2[Return to Text] In the Error Messages section, the three bolded red bytes were changed into zero-bytes for DOS 3.30 (actually, the first one was also moved to the end of the whole section and all the other bytes moved back by 1 in offset).
3[Return to Text] References to "David Litton" seem to be non-existent (apart from this website and
any others on early DOS history). The main reason for this lack of information about "Dave" is the fact that he died young (see below). One
person who emailed me, stated that Dave had taught an "Intel assembler course in Redmond UK," in the Spring of 1983 along with Ed Kiser (whose
name is found in the IBM PC 1.10 diskette); both were engineers on the original PC team at Boca Raton, FL, and the course was only for IBM employees who
lived in Europe.
We would appreciate any further information about the role he played in creating the MBR code which ended up becoming embedded in so many hard drives
across the world. His name also appears as the author of three DOS utilities as noted in our Forensic
Examination of the IBM DOS 1.00 Diskette; where we mentioned that he died around 1983.
Created: July 30, 2003 (30.07.2003).
Updated: December 10, 2024 (10.12.2024); March 2, 2013 (02.03.2013).
You can write to me using this: online reply form.
(It opens in a new window.)
The Starman's FREE TOOLS Page
MBR and Boot Records Index
The Starman's Realm Index Page