Windows 2000 MBR


Introduction

This page concentrates on a commented disassembly of the Windows 2000 MBR. The information below was contributed by Stephan Zaubzer from Austria which is why the MBR error messages are in German. It is assumed that the code will be the same in English versions.

Entire MBR record in hex and ASCII

The following is the MBR from the first physical sector (Cylinder 0, Side 0, Sector 1) of a hard drive with Windows 2000 installed.

Note on bytes found at hex offsets 001B8 to 001BD

According to The Starman "... these go way back to NT4 (or even earlier) and are often known as the NT Serial Number! Win2k calls it the Disk Signature and you can find it in many places in the REGISTRY; it's a Quad Word, so you have to reverse all 4 bytes if you want to look for it there... it will be different for every drive and will change if you zero-out the bytes and boot up with an NT/2K/XP system again. Also see his page on An Examination of the Standard MBR.


OFFSET  0  1  2  3  4  5  6  7    8  9  A  B  C  D  E  F   0123456789ABCDEF
---------------------------------------------------------------------------
00000  33 C0 8E D0 BC 00 7C FB - 50 07 50 1F FC BE 1B 7C   3.....|.P.P....|
00010  BF 1B 06 50 57 B9 E5 01 - F3 A4 CB BD BE 07 B1 04   ...PW...........
00020  38 6E 00 7C 09 75 13 83 - C5 10 E2 F4 CD 18 8B F5   8n.|.u..........
00030  83 C6 10 49 74 19 38 2C - 74 F6 A0 B5 07 B4 07 8B   ...It.8,t.......
00040  F0 AC 3C 00 74 FC BB 07 - 00 B4 0E CD 10 EB F2 88   ....t...........
00050  4E 10 E8 46 00 73 2A FE - 46 10 80 7E 04 0B 74 0B   N..F.s*.F..~..t.
00060  80 7E 04 0C 74 05 A0 B6 - 07 75 D2 80 46 02 06 83   .~..t....u..F...
00070  46 08 06 83 56 0A 00 E8 - 21 00 73 05 A0 B6 07 EB   F...V...!.s.....
00080  BC 81 3E FE 7D 55 AA 74 - 0B 80 7E 10 00 74 C8 A0   ....}U.t..~..t..
00090  B7 07 EB A9 8B FC 1E 57 - 8B F5 CB BF 05 00 8A 56   .......W.......V
000A0  00 B4 08 CD 13 72 23 8A - C1 24 3F 98 8A DE 8A FC   .....r#..$?.....
000B0  43 F7 E3 8B D1 86 D6 B1 - 06 D2 EE 42 F7 E2 39 56   C..........B..9V
000C0  0A 77 23 72 05 39 46 08 - 73 1C B8 01 02 BB 00 7C   .w#r.9F.s......|
000D0  8B 4E 02 8B 56 00 CD 13 - 73 51 4F 74 4E 32 E4 8A   .N..V...sQOtN2..
000E0  56 00 CD 13 EB E4 8A 56 - 00 60 BB AA 55 B4 41 CD   V......V.`..U.A.
000F0  13 72 36 81 FB 55 AA 75 - 30 F6 C1 01 74 2B 61 60   .r6..U.u0...t+a`
00100  6A 00 6A 00 FF 76 0A FF - 76 08 6A 00 68 00 7C 6A   j.j..v..v.j.h.|j
00110  01 6A 10 B4 42 8B F4 CD - 13 61 61 73 0E 4F 74 0B   .j..B....aas.Ot.
00120  32 E4 8A 56 00 CD 13 EB - D6 61 F9 C3 55 6E 67 81   2..V.....a..Ung.
00130  6C 74 69 67 65 20 50 61 - 72 74 69 74 69 6F 6E 73   ltige Partitions
00140  74 61 62 65 6C 6C 65 00 - 46 65 68 6C 65 72 20 62   tabelle.Fehler b
00150  65 69 6D 20 4C 61 64 65 - 6E 20 64 65 73 20 42 65   eim Laden des Be
00160  74 72 69 65 62 73 73 79 - 73 74 65 6D 73 00 42 65   triebssystems.Be
00170  74 72 69 65 62 73 73 79 - 73 74 65 6D 20 6E 69 63   triebssystem nic
00180  68 74 20 76 6F 72 68 61 - 6E 64 65 6E 00 00 00 00   ht vorhanden....
00190  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
001A0  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
001B0  00 00 00 00 00 2C 48 6E - 32 B5 32 B5 00 00 80 01   .....,Hn2.2.....
001C0  01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00 00 00   ......?...K.....
001D0  81 0A 0F FE FF FF 8A F5 - 7F 00 7A AB D1 08 00 00   ..........z.....
001E0  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
001F0  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 55 AA   ..............U.

MBR - Program

The program code differs a bit from that discussed in MBR - Program for Windows 95b but performs the same functions.

Disassembly of MBR Program Code

The MBR sector is initially loaded into memory at 0000:7C00 but it immediately relocates itself to 0000:0600.

		NOW AT 0000:7C00. Copying itself to 0000:0600

0000:7C00 33C0          XOR	AX,AX		Set AX to zero
0000:7C02 8ED0          MOV	SS,AX           Set SS (Stack Segment) to zero
0000:7C04 BC007C        MOV	SP,7C00         Set Stack Pointer to 0x7C00 (Stack now at 0000:7C00)
0000:7C07 FB            STI	                Set Interrupt Flag (External Interrupts accepted)
0000:7C08 50            PUSH	AX              Save AX
0000:7C09 07            POP	ES              ES (Extra Segment Register) now zero
0000:7C0A 50            PUSH	AX              Save AX
0000:7C0B 1F            POP	DS              DS (Data Segment Register) now zero
0000:7C0C FC            CLD	                Clear Direction Flag
0000:7C0D BE1B7C        MOV	SI,7C1B         SI (Source Index) now 0x7C1B
0000:7C10 BF1B06        MOV	DI,061B         DI (Destination Index now 0x61B
0000:7C13 50            PUSH	AX              Save AX
0000:7C14 57            PUSH	DI              Save DI
0000:7C15 B9E501        MOV	CX,01E5         CX now 0x01E5 (d485)
0000:7C18 F3            REPZ	                Repeat Next Line decrementing CX until CX = 0
0000:7C19 A4            MOVSB	                Move [DS:SI] to [ES:DI] and increment SI, DI
0000:7C1A CB            RETF	                Return from far: POP IP, POP CS and jmp to CS:IP (0000:061B)

		NOW AT 0000:061B

0000:061B BDBE07        MOV	BP,07BE         Set BP (Base Pointer) to 07BE (Beginning of Partition Table)
0000:061E B104          MOV	CL,04           Fill CL with 04
0000:0620 386E00        CMP	[BP+00],CH      Compare Bootentry [SS:BP] with CH (zero)
0000:0623 7C09          JL	062E            Jmp to OTHER ACTIVE PRT if Bootentry >= 0x80 (Jump Distance indicated by 1 byte in Opcode:09)
0000:0625 7513          JNZ	063A            Jmp to INVLD PRT TBL if Bootentry <>0x00
0000:0627 83C510        ADD	BP,+10          Point to next Partition Entry
0000:062A E2F4          LOOP	0620            (Jump Distanve indicated by 1 byte, negative distances in 2's complement)
0000:062C CD18          INT	18              No Bootable Partition... Goto Rom Basic

		:OTHER ACTIVE PRT?

0000:062E 8BF5          MOV	SI,BP           SI points now to 1st Byte of active Partitionentry
0000:0630 83C610        ADD	SI,+10          now, points to 1st Byte of next Partition
0000:0633 49            DEC	CX
0000:0634 7419          JZ	064F            Jmp to LABEL 3 If no Partitionenty left...
0000:0636 382C          CMP	[SI],CH         Compare Bootentry of next Partition
0000:0638 74F6          JZ	0630            If zero, test next partition
0000:063A A0B507        MOV	AL,[07B5]       Fill AL with byte at 0000:07B5 (Pointer to message)

		:DISPLAY MESSAGE (Display message, and hang system in infinite loop)
	
0000:063D B407          MOV	AH,07           Fill AH with 0x07
0000:063F 8BF0          MOV	SI,AX           Fill SI with 0x07** (** for each message different)
		:MESSAGE LOOP
0000:0641 AC            LODSB	                Load DS:SI (0000:072C) into AL, Increment SI
		:INFINITE LOOP
0000:0642 3C00          CMP	AL,00           Compare AL with 0x00
0000:0644 74FC          JZ	0642            jmp to INFINITE LOOP if AL zero
0000:0646 BB0700        MOV	BX,0007         Set Screen Attributes
0000:0649 B40E          MOV	AH,0E           Fill AH with 0x0E
0000:064B CD10          INT	10              INT 10 AH=0E Print character stored in AL
0000:064D EBF2          JMP	0641            Jmp to MESSAGE LOOP

		:LABEL 3

0000:064F 884E10        MOV	[BP+10],CL      Set beginning of next Partition entry to zero
0000:0652 E84600        CALL	069B		PUSH IP, jump to 0000:069B
0000:0655 732A          JNB	0681			IF CF = 0 (Bootrecord allready read) jump to ...	
0000:0657 FE4610        INC	BYTE PTR [BP+10]	Increase first byte of next partitiontableentry
0000:065A 807E040B      CMP	BYTE PTR [BP+04],0B	Check if Partition is FAT32
0000:065E 740B          JZ	066B			Jump if FAT32
0000:0660 807E040C      CMP	BYTE PTR [BP+04],0C	Check if partition is FAT32 LBA Mapped
0000:0664 7405          JZ	066B			Jump if FAT32 LBA Mapped
0000:0666 A0B607        MOV	AL,[07B6]		AL now 48
0000:0669 75D2          JNZ	063D			Display Message: "Fehler beim Laden des Betriebssystems"
0000:066B 80460206      ADD	BYTE PTR [BP+02],06	increase Sectornumber by 6
0000:066F 83460806      ADD	WORD PTR [BP+08],+06	Increase Starting LBA (1st 2 Bytes) by 6
0000:0673 83560A00      ADC	WORD PTR [BP+0A],+00	If overflow in last operation, correct
0000:0677 E82100        CALL	069B			Call SUBROUTINE
0000:067A 7305          JNB	0681			IF CF = 0 (Bootrecord already read) jump to
0000:067C A0B607        MOV	AL,[07B6]		AL now now 48
0000:067F EBBC          JMP	063D			Display Message: "Fehler beim Laden des Betriebssystems"
0000:0681 813EFE7D55AA  CMP	WORD PTR [7DFE],AA55	Check for MBR Signature
0000:0687 740B          JZ	0694			If signature ok, Jump to ...
0000:0689 807E1000      CMP	BYTE PTR [BP+10],00	Look if Next Partitionenty = 0
0000:068D 74C8          JZ	0657			If yes, goto 0657, and if Fat32, Read safety boot record
0000:068F A0B707        MOV	AL,[07B7]	Al now messagepointer (6E)
0000:0692 EBA9          JMP	063D		Show message (Betriebssystem nicht vorhanden)
0000:0694 8BFC          MOV	DI,SP		Stackpointer (7C00) now DI
0000:0696 1E            PUSH	DS		Push DS (0000)
0000:0697 57            PUSH	DI		Push DI (7C00)
0000:0698 8BF5          MOV	SI,BP		SI points now to Partitionentry begin of first Partition
0000:069A CB            RETF			Start Bootcode of OS

		:DRIVEPARAMETERS (called from 0000:0652 and 0000:0677)

0000:069B BF0500        MOV	DI,0005         Fill DI with 0x0005
0000:069E 8A5600        MOV	DL,[BP+00]      Fill DL with 0x80
0000:06A1 B408          MOV	AH,08           Fill AH with 0x08
0000:06A3 CD13          INT	13              Get Drive Parameters
0000:06A5 7223          JB	06CA            If Error, jmp to READ SECTOR
0000:06A7 8AC1          MOV	AL,CL           AL (0-5) max sectornumber, (6-7) high bits of cylinder
0000:06A9 243F          AND	AL,3F           Set Bit 7 and 8 of AL zero (now AL = max Sector number)
0000:06AB 98            CBW			Expand AL to AX
0000:06AC 8ADE          MOV	BL,DH           now BL = maximum Head number
0000:06AE 8AFC          MOV	BH,AH           now BH = 00
0000:06B0 43            INC	BX              now BX = maximum Head number + 1
0000:06B1 F7E3          MUL	BX		Multiply BX by AX (Sectornumber by Headnumber(+1)) and store it in DX:AX
0000:06B3 8BD1          MOV	DX,CX		Move CX (maximum cylindernumber and sectornumber) to DX
0000:06B5 86D6          XCHG	DL,DH		Now, Bits 0-7 = max Cyl number, 8-13 max heads, 14-15 = High cyl-bits.
0000:06B7 B106          MOV	CL,06		CL now 0x06
0000:06B9 D2EE          SHR	DH,CL		Shift DH 6 bits to the right
0000:06BB 42            INC	DX		Now max Cyl-number + 1
0000:06BC F7E2          MUL	DX		Multiply max Cyl-number(+1) by result of prior multiplication. DX:AX now contains max numbers of Sectors on HD by CHS-Adressing
0000:06BE 39560A        CMP	[BP+0A],DX	Compare DX with Higher Word of Distance of Bootsector of active partition
0000:06C1 7723          JA	06E6		If Partitiontable entry bigger, goto CHECK FOR INT 13 EXT
0000:06C3 7205          JB	06CA		If smaller, goto READ SECTOR
0000:06C5 394608        CMP	[BP+08],AX	Compare lower word
0000:06C8 731C          JNB	06E6		If NOT smaller, goto ...

		:READ SECTOR (without INT13 Extension)

0000:06CA B80102        MOV	AX,0201         Read one sector (???Why read, when error occured while getting drive parameters???
0000:06CD BB007C        MOV	BX,7C00         to 0000:7C00
0000:06D0 8B4E02        MOV	CX,[BP+02]      set cylinder and sector number
0000:06D3 8B5600        MOV	DX,[BP+00]      set drive and head number
0000:06D6 CD13          INT	13              Read Bootsector of Bootpartition
0000:06D8 7351          JNB	072B            If successful, jmp to 0000:072B
0000:06DA 4F            DEC	DI              DI now 0x0004
0000:06DB 744E          JZ      072B		Jump if DI = 0x0000 (5 times tried, NOT successful)
0000:06DD 32E4          XOR     AH,AH		Set AH zero
0000:06DF 8A5600        MOV     DL,[BP+00]	DL now 0x80
0000:06E2 CD13          INT     13		Diskreset
0000:06E4 EBE4          JMP     06CA		Retry (READ SECTOR)

		:CHECK FOR INT 13 EXT

0000:06E6 8A5600        MOV     DL,[BP+00]	DL now 80
0000:06E9 60            PUSHA   		PUSH AX, CX, DX, BX, SP, BP, SI and DI
0000:06EA BBAA55        MOV     BX,55AA		Set BX for Extended INT 13h Check
0000:06ED B441          MOV     AH,41		Set AX for Extended INT 13h Check
0000:06EF CD13          INT     13		Check for INT 13h extensions
0000:06F1 7236          JB      0729		Jump to 0729 if NOT supported
0000:06F3 81FB55AA      CMP     BX,AA55		Check if installed
0000:06F7 7530          JNZ     0729		Jump to 0729 if NOT installed
0000:06F9 F6C101        TEST    CL,01		Test if extended Disk Access functions supported
0000:06FC 742B          JZ      0729		If not Supported, jump to 0729

		: READ SECTOR WITH INT 13 Ext.

0000:06FE 61            POPA    		POP DI, SI, BP, SP(*), BX, DX, CX, AX, ((*) Doesn't get stored)
0000:06FF 60            PUSHA   		Push Registers again 
0000:0700 6A00          PUSH    00		Push 0x0000 	    /High DWord of LBA Adress 
0000:0702 6A00          PUSH    00			Push 0x0000 \High DWord of LBA Adress
0000:0704 FF760A        PUSH    WORD PTr [BP+0A]	PUSH Starting LBA (High word) /Low DWord of LBA Adress
0000:0707 FF7608        PUSH    WORD PTr [BP+08]	PUSH Starting LBA (Low word)  \Low Dword of LBA Adress
0000:070A 6A00          PUSH    00			Push 0x0000 (Adress of readbuffer)
0000:070C 68007C        PUSH    7C00		Push 0x7C00 (Adress of readbuffer) (0000:7C00)
0000:070F 6A01          PUSH    01		Push 0x0001 (number of sectors to read)
0000:0711 6A10          PUSH    10		Push 0x0010
0000:0713 B442          MOV     AH,42		AH now 42 For INT 13 Extended read
0000:0715 8BF4          MOV     SI,SP		DS:SI points to stack for INT13 extended read
0000:0717 CD13          INT     13		Read
0000:0719 61            POPA    		POP 16 bytes
0000:071A 61            POPA    		POP 16 bytes
0000:071B 730E          JNB     072B		If Successful, jump to RET
0000:071D 4F            DEC     DI		Dec DI
0000:071E 740B          JZ      072B		If Zero, jump to RET
0000:0720 32E4          XOR     AH,AH		AH now zero (for disk reset)
0000:0722 8A5600        MOV     DL,[BP+00]	DL now 80	
0000:0725 CD13          INT     13		Diskreset
0000:0727 EBD6          JMP     06FF		Try Again
0000:0729 61            POPA    		POP DI, SI, BP, SP(*), BX, DX, CX, AX, ((*)Doesn't get stored)
0000:072A F9            STC     		Set Carry Flag (Sector not yet read)
0000:072B C3            RET     		POP IP, goto 0000:IP
------------------------------------------------ END OF BOOTCODE ------------------------------------------------

		MESSAGE AREA
	 
	   0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F	
------------------------------------------------------------------------------
00000720 |                                      55 6E 67 81               Ung	Invalid Partition Table
00000730 | 6C 74 69 67 65 20 50 61  72 74 69 74 69 6F 6E 73   ltige Partitions
00000740 | 74 61 62 65 6C 6C 65 00  46 65 68 6C 65 72 20 62   tabelle.Fehler b	Error loading operating
00000750 | 65 69 6D 20 4C 61 64 65  6E 20 64 65 73 20 42 65   eim Laden des Be	system
00000760 | 74 72 69 65 62 73 73 79  73 74 65 6D 73 00 42 65   triebssystems.Be	No operating system
00000770 | 74 72 69 65 62 73 73 79  73 74 65 6D 20 6E 69 63   triebssystem nic
00000780 | 68 74 20 76 6F 72 68 61  6E 64 65 6E 00 00 00 00   ht vorhanden....
00000790 | 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000007A0 | 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
	 |		MESSAGE POINTERS
000007B0 | 00 00 00 00 00 2C 48 6E  32 B5 32 B5 00 00 
         |              PARTITIONTABLE                80 01   .....,Hn22...
000007C0 | 01 00 07 FE BF 09 3F 00  00 00 4B F5 7F 00 00 00   ....?...K...
000007D0 | 81 0A 0F FE FF FF 8A F5  7F 00 7A AB D1 08 00 00   ...z...
000007E0 | 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000007F0 | 00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 AA   ..............U

LAST WORD (offset 07FE): 55AA (BOOT SECTOR SIGNATURE)

If you have comments or suggestions, email me at Ray Knights or the main author Stephan Zaubzer

MBR/Boot Index

Home Page

This page was created on 5 October 2002, last updated on 19 March 2010.