; microsoft.windows.2000.mbr.asm.txt ; Windows 2000 ( NT5.0 ) ; MBR ( Master Boot Record ) by Daniel B. Sedory ; http://thestarman.pcministry.com 7C00 33C0 XOR AX,AX ; Zero out the Accumulator and 7C02 8ED0 MOV SS,AX ; Stack Segment register. 7C04 BC007C MOV SP,7C00 ; Set Stack Pointer to 0000:7C00 7C07 FB STI ; Enable Interrupts 7C08 50 PUSH AX ; (AX=0 at this time) 7C09 07 POP ES ; Zero-out Extra Segment 7C0A 50 PUSH AX ; (AX=0 at this time) 7C0B 1F POP DS ; Zero-out Data Segment 7C0C FC CLD ; Clear Direction Flag 7C0D BE1B7C MOV SI,7C1B ; Source Index: Copy from here... 7C10 BF1B06 MOV DI,061B ; Destination Index: Copy to here: ; Code will begin at: 0000:061B 7C13 50 PUSH AX ; Set up Segment(AX) and Offset(DI) 7C14 57 PUSH DI ; for jump to 0000:061B. 7C15 B9E501 MOV CX,01E5 ; Set up Counter (CX) to copy ; (1E5h) 485 bytes of code. 7C18 F3 REP ; REPeat the following MOVSB ; instruction for 'CX' times. 7C19 A4 MOVSB ; Copy one byte at a time. 7C1A CB RETF ; Use RETF to do Jump to where we ; copied the code: 0000:061B. ; Since the preceding routine copies the remainder of the code to 0000:061B ; through 0000:07FF and continues its execution there, the following ; addresses have been changed to reflect the code's actual location in ; memory at the time of execution. ; This next section of code tries to find an ACTIVE (i.e., bootable) ; entry in the Partition Table. The first byte of an entry indicates ; if it's bootable(an 80h) or not(a 00h); any other values in these ; locations means the Table is invalid! If none of the four entries ; in the Table is active, the 'Invalid' error message is displayed. ; [Previous Microsoft MBR code used the SI register here rather than ; BP which can be seen at offsets 061B, 0620 and 0627 below.] 061B BDBE07 MOV BP,07BE ; Location of first entry ; in the partition table ; (see Sample Table here). 061E B104 MOV CL,04 ; Maximum of four entries. 0620 386E00 CMP [BP+00],CH ; CH=0 (from Counter decrement ; above), so CoMPare first byte ; of entry [BP+00] to Zero. Any- ; thing else will be 'less than'. 0623 7C09 JL 062E ; Found a possible boot entry ; let's check it out more at 062E ; or keep searching here... 0625 7513 JNZ 063A ; -> "Invalid partition table" 0627 83C510 ADD BP,+10 ; Checking the next entry... ; (10h = 16 bytes per entry) 062A E2F4 LOOP 0620 ; Go back & check next Entry... ; unless CL=0 (tried all four). 062C CD18 INT 18 ; Checked all 4; 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. ; An Active partition was found, but we must check all other entries ; for being non-bootable (first byte = 00h), or there's an error! ; (Only one entry in the Partition Table can be marked as 'Active.') 062E 8BF5 MOV SI,BP ; Copy Base Pointer value of 07BE into Source Index Register; use 0630 83C610 ADD SI,+10 ; SI,+10 (16 bytes) to see if any more partitions are left. 0633 49 DEC CX ; If CX=0, then we're done here, 0634 7419 JZ 064F ; so Jump to ID-type checking! 0636 382C CMP [SI],CH ; Compare entry's first byte [SI] 0638 74F6 JZ 0630 ; to Zero (CH=0). If it's not zero, we immediately fall into the following error routine: ; Note: When the last character of any Error Message has been displayed ; on screen, the instructions at offsets 0642 and 0644 lock computer's ; execution into an infinite loop! You must reboot the machine. Int 10, ; Function 0Eh (Teletype Output) is used to display the characters. 063A A0B507 MOV AL,[07B5] ;[7B5]=2C Together with the '07' 063D B407 MOV AH,07 ; in AH, this gives us an offset 063F 8BF0 MOV SI,AX ; of 72C in the Source Index Reg. 0641 AC LODSB ; Load character into AL from [SI]. 0642 3C00 CMP AL,00 ; Have we reached end of message marker?(00) If so, then lock 0644 74FC JZ 0642 ; execution into infinite loop. 0646 BB0700 MOV BX,0007 ; Display page 0, normal white on black characters. 0649 B40E MOV AH,0E ; Teletype Output.. displays only 064B CD10 INT 10 ; one character at a time. 064D EBF2 JMP 0641 ; Go back for another character! 064F 884E10 MOV [BP+10],CL 0652 E84600 CALL 069B 0655 732A JNB 0681 ; (jae short 0681) 0657 FE4610 INC BYTE PTR [BP+10] 065A 807E040B CMP BYTE PTR [BP+04],0B 065E 740B JZ 066B 0660 807E040C CMP BYTE PTR [BP+04],0C 0664 7405 JZ 066B 0666 A0B607 MOV AL,[07B6] ; [7B6] = 44 + 700 -> 744 0669 75D2 JNZ 063D ; Display: "Error loading operating system" 066B 80460206 ADD BYTE PTR [BP+02],06 066F 83460806 ADD WORD PTR [BP+08],+06 0673 83560A00 ADC WORD PTR [BP+0A],+00 0677 E82100 CALL 069B 067A 7305 JNB 0681 ; (jae short 0681) 067C A0B607 MOV AL,[07B6] ; [7B6] = 44 + 700 -> 744 067F EBBC JMP 063D ; Display: "Error loading operating system" 0681 813EFE7D55AA CMP WORD PTR [7DFE],AA55 ; Check for "Magic Number" 0687 740B JZ 0694 ; at end of sector and jump to Boot Record... 0689 807E1000 CMP BYTE PTR [BP+10],00 068D 74C8 JZ 0657 068F A0B707 MOV AL,[07B7] ; [7B7] = 63 + 700 -> 763 0692 EBA9 JMP 063D ; Display: "Missing operating system" ; Set up the CS and IP Registers for Jumping to the Volume Boot Record ; loaded into Memory at 0000:7C00 using a FAR Return instruction (which ; takes IP and then CS off the STACK before jumping to CS:IP); a RETF ; was already used at 7C10 through 7C1A above. 0694 8BFC MOV DI,SP ; STACK Pointer is still 7C00. 0696 1E PUSH DS ; DS is 0000 at this time. 0697 57 PUSH DI ; SP --> DI (now 7C00). 0698 8BF5 MOV SI,BP ; BP (still 07BE) -> SI for use by Boot Record. 069A CB RETF ; Jumps to 0000:7C00 ; The following code first performs an INT 13 Function 08 BIOS routine ; called "Get Drive Parameters" (if successful, there will be no Carry Flag ; and AH will be zero); returns Max. Head number in DH and the number of ; drives in DL. The Max. Cylinder number must be calculated from bits 7 and ; 6 of CL (two high bits) and CH (low eight bits) to form a 10-bit number; ; thus it can be no larger than 3FFh (or 1023). Bits 5 thru 0 of CL are the ; Max. Sector number -> 3Fh (or 63) is the largest value there. 069B BF0500 MOV DI,0005 069E 8A5600 MOV DL,[BP+00] ;| 80 -> DL (First Hard Drive) 06A1 B408 MOV AH,08 ;| INT 13, Function 08 06A3 CD13 INT 13 ;| "Get Drive Parameters" 06A5 7223 JB 06CA 06A7 8AC1 MOV AL,CL 06A9 243F AND AL,3F 06AB 98 CBW ; Convert Byte to Word. 06AC 8ADE MOV BL,DH 06AE 8AFC MOV BH,AH 06B0 43 INC BX 06B1 F7E3 MUL BX 06B3 8BD1 MOV DX,CX 06B5 86D6 XCHG DL,DH 06B7 B106 MOV CL,06 06B9 D2EE SHR DH,CL 06BB 42 INC DX 06BC F7E2 MUL DX 06BE 39560A CMP [BP+0A],DX 06C1 7723 JA 06E6 ; Check for Extended INT 13. 06C3 7205 JB 06CA 06C5 394608 CMP [BP+08],AX 06C8 731C JNB 06E6 ; Check for Extended INT 13. 06CA B80102 MOV AX,0201 ;| INT 13, Function 2 06CD BB007C MOV BX,7C00 ;| (ES):BX = Memory Buffer 06D0 8B4E02 MOV CX,[BP+02] ;| 06D3 8B5600 MOV DX,[BP+00] ;| 06D6 CD13 INT 13 ;| "Read 1 Sector into Memory" 06D8 7351 JNB 072B 06DA 4F DEC DI 06DB 744E JZ 072B 06DD 32E4 XOR AH,AH ;| INT 13, Function 0 06DF 8A5600 MOV DL,[BP+00] ;| DL=Drive Number 06E2 CD13 INT 13 ;| "Reset DISK System" 06E4 EBE4 JMP 06CA ; The following are the "INT 13 Extensions Installation Check" and ; the Extended READ sectors from Hard Drive (Function 42h) routines. 06E6 8A5600 MOV DL,[BP+00] ;| DL = Drive Number. 06E9 60 * PUSHA ; PUSH all Registers onto Stack. 06EA BBAA55 MOV BX,55AA ;| BX must be set to 55AAh or the ;| Function won't work! 06ED B441 MOV AH,41 ;| INT 13 Function 41h. 06EF CD13 INT 13 ;| "Check for INT 13 Extensions" 06F1 7236 JB 0729 ; Was operation successful? If not, Return (with CF set)! 06F3 81FB55AA CMP BX,AA55 ; The contents of BX are changed into AA55h if EXTs installed! 06F7 7530 JNZ 0729 ; Are they installed? If not, Return (with CF set)! 06F9 F6C101 TEST CL,01 06FC 742B JZ 0729 ; Return (with Carry Flag set)! 06FE 61 * POPA ; POP all Registers from Stack. 06FF 60 * PUSHA ; PUSH all Registers onto Stack. 0700 6A00 * PUSH 0000 ;| 0702 6A00 * PUSH 0000 ;| 0704 FF760A PUSH [BP+0A] ;| 0707 FF7608 PUSH [BP+08] ;| 070A 6A00 * PUSH 0000 ;| 070C 68007C * PUSH 7C00 ;| 070F 6A01 * PUSH 0001 ;| 0711 6A10 * PUSH 0010 ;| 0713 B442 MOV AH,42 ;| INT 13 Function 42h 0715 8BF4 MOV SI,SP ;| (DS):SI = Disk Address Packet which was PUSHed onto STACK to use with this function! 0717 CD13 INT 13 ;| Extended READ of drive sectors. 0719 61 * POPA ; POP Packet values from Stack. 071A 61 * POPA ; POP all Registers from Stack. 071B 730E JNB 072B ; Return without Reset of disks. 071D 4F DEC DI 071E 740B JZ 072B ; Return without Reset of disks. 0720 32E4 XOR AH,AH ;| INT 13 Function 0 0722 8A5600 MOV DL,[BP+00] ;| DL=Drive Number 0725 CD13 INT 13 ;| "Reset DISK System" 0727 EBD6 JMP 06FF 0729 61 * POPA 072A F9 STC ; SET Carry Flag 072B C3 RET ;Location of Error Messages and ;Message Offsets in Memory ; C D E F ;072C 49 6E 76 61 Inva ;0730 6C 69 64 20 70 61 72 74 69 74 69 6F 6E 20 74 61 lid partition ta ;0740 62 6C 65 00 45 72 72 6F 72 20 6C 6F 61 64 69 6E ble.Error loadin ;0750 67 20 6F 70 65 72 61 74 69 6E 67 20 73 79 73 74 g operating syst ;0760 65 6D 00 4D 69 73 73 69 6E 67 20 6F 70 65 72 61 em.Missing opera ;0770 74 69 6E 67 20 73 79 73 74 65 6D 00 00 00 00 00 ting system..... ;0780 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ;0790 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ;07A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ;07B0 00 00 00 00 00 2C 44 63 .....,Dc ; 0 1 2 3 4 5 6 7 8 9 A B C D E F ;Location of Sample Disk Signature ;and Partition Table in Memory ; 8 9 A B C D E F ;07B8 A8 E1 A8 E1 00 00 80 01 ........ ;07C0 01 00 07 7F BF FD 3F 00 00 00 C1 40 5E 00 00 00 ......?....@^... ;07D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ;07E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ;07F0 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