作者nfsong (图书馆我来了)
看板PCSH91_305
标题An Examination of the Standard MBR
时间Sun Jan 18 00:17:36 2009
http://www.geocities.com/thestarman3/asm/mbr/STDMBR.htm
An Examination of the Assembly Code
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):
7C00 FA CLI ; Disable maskable Interrupts
7C01 33C0 XOR AX,AX ; Zero out both the Accumulator and
7C03 8ED0 MOV SS,AX ; the Stack Segment register.
7C05 BC007C MOV SP,7C00 ; Set Stack Pointer to 0000:7C00
7C08 8BF4 MOV SI,SP ; Source Index: Copy from here...
7C0A 50 PUSH AX
7C0B 07 POP ES ; Zero-out Extra Segment
7C0C 50 PUSH AX
7C0D 1F POP DS ; Zero-out Data Segment
7C0E FB STI ; Enable Interrupts again
7C0F FC CLD ; Clear Direction Flag (df=0).
7C10 BF0006 MOV DI,0600 ; Destination Index: New copy of
; code will begin at 0000:0600
7C13 B90001 MOV CX,0100 ; Copy 256 Words (512 bytes)
; (100 hex = 256 decimal)
7C16 F2 (*) REP (*) ; REPeat the following MOVSW
; instruction for 'CX' times(*).
7C17 A5 MOVSW ; Copy two bytes at a time.
7C18 EA1D060000 JMP 0000:061D ; Jump to new copy of code...
; Since the preceding routine copies itself and all of the following
; code to 0000:0600 and then jumps to 0000:061D before continuing to
; run, the following addresses have been changed to reflect the
; code's actual location in memory at the time of execution.
; 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
; (see Sample Table below).
0620 B304 MOV BL,04 ; Maximum of 4 Table Entries.
0622 803C80 CMP BYTE PTR [SI],80 ; Is this one bootable (80h)?
0625 740E JE 0635 ; Yes, so jump to next test!
0627 803C00 CMP BYTE PTR [SI],00 ; No; is it a 00? If not, it's
062A 751C JNE 0648 ; an Invalid partition table.
062C 83C610 ADD SI,+10 ; Check next entry for 80h ...
; (10h = 16 bytes per entry)
062F FECB DEC BL ; Subtract 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.')
; 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 to boot from another (second, etc.) drive! ]
0637 8B4C02 MOV CX,[SI+02] ; Sector -> CL / Cylinder -> CH
063A 8BEE MOV BP,SI ; Save offset of Active Entry
; pass to Volume Boot Sector.
063C 83C610 ADD SI,+10 ; Do next Table Entry
063F FECB DEC BL ; Is this the last entry?
0641 741A JZ 065D ; All Entries look OK, so...
; -> Jump to Boot-routine!
0643 803C00 CMP BYTE PTR [SI],00 ; Non-bootable entry (00h)?
0646 74F4 JE 063C ; Yes, so check next entry.
; If there was an error, then this next routine displays the message that
; SI points to. After printing the ASCII-Z string (null terminated), the
; program 'locks up' by going into an infinite loop (at 065B):
0648 BE8B06 MOV SI,068B ; -> "Invalid partition table"
064B AC LODSB ; Load byte at [SI] into AL ...
; and increment the SI value.
064C 3C00 CMP AL,00 ; Is it a zero-byte yet ?
064E 740B JE 065B ; If yes, were done. If not ...
0650 56 PUSH SI ; Store string pointer on stack.
0651 BB0700 MOV BX,0007 ; Use Function 0E (Write Text) of
0654 B40E MOV AH,0E ; DOS Interrupt 10 to send the
0656 CD10 INT 10 ; character in AL to the screen.
0658 5E POP SI
0659 EBF0 JMP 064B
065B EBFE JMP 065B ; Infinite Loop. You must
; power-down or Reboot!
; 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 call below.
065D BF0500 MOV DI,0005 ; Retry 5 times (if necessary)...
0660 BB007C MOV BX,7C00 ; Load OS Boot Sector to 0000:7C00
0663 B80102 MOV AX,0201 ; Function 02h. Read 1 sector.
0666 57 PUSH DI
0667 CD13 INT 13 ; Note: This old INT 13 Read
; is limited to 1024 cylinders.
0669 5F POP DI
066A 730C JNC 0678 ; Carry Flag set? If no, jump!
066C 33C0 XOR AX,AX ; Yes, so we had an error! Must
066E CD13 INT 13 ; ...reset drive (Function 00h)
0670 4F DEC DI ; Decrement counter (if > 0)
0671 75ED JNZ 0660 ; and try again...
0673 BEA306 MOV SI,06A3 ; Or, declare: "Error loading
0676 EBD3 JMP 064B ; operating system" and hang!
; 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.
; 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.
0678 BEC206 MOV SI,06C2 ; -> "Missing operating system"
; Set up SI, in case we have an
; error in the Boot Sector read.
067B BFFE7D MOV DI,7DFE ; Point to the last Word of Boot
; Sector. It should be AA55 Hex.
067E 813D55AA CMP WORD PTR [DI],AA55 ; Is it? ('Signature' Check.)
0682 75C7 JNE 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!
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.115.4.134