📄 win98se硬盘主引导记录代码反汇编分析.txt
字号:
; 硬盘主引导记录代码分析 by pp2hands.126.com 2001/10/01
;
; 本段代码取自由WIN98SE之"FDISK /MBR"命令处理过的硬盘
;
; PC机之ROM在上电及POST自检成功后,将本段代码从硬盘之0面0道1扇区位置读出,
; 放置在0:7C00处,寄存器设置如下:
; CS=DS=ES=SS=0. IP=7C00h, SP=0400H
;
; 本段代码负责从代码尾部之4个分区表项中找出可以引导的项,读出其引导记录引导之。
;
; 流程如下:
;
; 1). 将代码从0:7C00移至0:600
; 2). 检查4个分区表项有效性:
; a).有否可引导分区?
; 无则转ROM BASIC(INT 18)
; b).多个引导分区?
; 是则显示'Invalid partition'后挂机
; c).可引导标志为0与80h之外的无效值?
; 是则显示'Invalid partition'后挂机
; 3). 找寻唯一有效引导分区项目,将之对应的引导记录读入0:7C00,
; a).读入方式有二种,
; 一般采用经典的INT13 AH=2号调用,
; 如果是0Eh系统ID,则使用另一种新型BIOS之
; INT13 AH=42号扩展功能
; b).如果读入操作错误(包括读入内容无效)就重复读10次,
; 如果系统ID为0B,0C,因为它们在原引导记录之后6个扇区位置
; 还有一个引导记录的备份,就从第6次开始读该备份
; c).仍然错误则转显示'Missing operating system'或
; 'Error loading operating system'后挂机
; 4). 转向有效的引导记录0:7C00
;
; 它载入引导记录至0:7C00,转向它时,寄存器设置如下:
; CS=DS=ES=SS=0. IP=7C00h, DI=SP=7C00H, SI=BP-->指向引导中的分区表项
;
;
.386p
_data segment public
assume cs:_data, ds:_data
org 600h
mbr proc far
; The ROM in the IBM PC starts the boot process by performing a hardware
; initialization and a verification of all external devices. If all goes
; well, it will then load from the boot drive the sector from track 0, head 0,
; sector 1. This sector is placed at physical address 07C00h. The initial
; registers are set up as follows: CS=DS=ES=SS=0. IP=7C00h, SP=0400H, CLI.
;
0000:0600 start: ; relocate to 0:0600
0000:0600 33 C0 xor ax,ax
0000:0602 8E D0 mov ss,ax
0000:0604 BC 7C00 mov sp,7C00h ; new stack at 0:7c00
0000:0607 FB sti ; interrupts ok now
0000:0608 50 push ax
0000:0609 07 pop es
0000:060A 50 push ax
0000:060B 1F pop ds ; ES:DS=0
0000:060C FC cld ; movsb direction: forward
0000:060D .BE 7C1B mov si,offset loc_restart - 600h + 7C00h
0000:0610 .BF 061B mov di,offset loc_restart
0000:0613 50 push ax
0000:0614 57 push di
0000:0615 B9 01E5 mov cx,offset code_end - offset loc_restart
0000:0618 F3/ A4 rep movsb ; move CX byte data from DS:SI to ES:DI
0000:061A CB retf ; return address = 0:061b = offset loc_loc_restart
; look throught partition table
; for valid & activate entry
0000:061B loc_restart:
0000:061B .BE 07BE mov si,offset partition_tab
0000:061E B1 04 mov cl,4 ; number of table entrie
0000:0620 loc_nextpe:
0000:0620 38 2C cmp [si],ch ; is boot indicator <= 0(ch=0)?
0000:0622 7C 09 jl short loc_boot ; < 0, that is 80h, bootable entry found
0000:0624 75 15 jnz short loc_bad ; !=0 & !<0, that is invalid (0 & 80h only)
0000:0626 83 C6 10 add si,10h ; = 0, go partition next entry
0000:0629 E2 F5 loop loc_nextpe
; no more entries to lookup
0000:062B CD 18 int 18h ; no bootable entries - go to rom basic
0000:062D loc_boot: ; xref 0622
0000:062D 8B 14 mov dx,[si] ; head and drive to boot from
0000:062F 8B EE mov bp,si ; save table entry address to pass to partition boot record
0000:0631 loc_nextrpe: ; all remaining entries should begin with 0
0000:0631 83 C6 10 add si,10h ; next table entry
0000:0634 49 dec cx ; # entries left
0000:0635 74 16 jz short loc_tabok ; all entries look ok
0000:0637 38 2C cmp [si],ch ; other entries = 0 ?
0000:0639 74 F6 je loc_nextrpe ; yes, this one is ok
0000:063B loc_bad: ; found a invalid entry :
; A). from 0624: boot id !=0 and !=80h
; B). from 0639: multi entries with id=80h
0000:063B .BE 0710 mov si,offset msg1+1 ; 'Invalid partition'
0000:063E loc_halt: ; show msg then halt
0000:063E 4E dec si
0000:063F loc_msg: ; xref 064B, 06BA
0000:063F AC lodsb ; got a message char
0000:0640 3C 00 cmp al,0
0000:0642 74 FA je loc_halt ; no more char, then halt
0000:0644 BB 0007 mov bx,7
0000:0647 B4 0E mov ah,0Eh
0000:0649 CD 10 int 10h ; then display it: ah=functn 0Eh
; write char al, bl=attr, teletype mode
000:064B loc_msgh: ; xref 06BF
0000:064B EB F2 jmp short loc_msg ; do the entire message
; Tempory variable in heap:
; bp + 24h db ? ; boot record drive
; bp + 25h dw ? ; boot record sector (2nd copy of boot record)
0000:064D loc_tabok: ; xref 0635
0000:064D 89 46 25 mov [bp+25h],ax ; clear sector/cyl of 2nd copy of boot recordto 0
0000:0650 96 xchg si,ax ; si=0
0000:0651 8A 46 04 mov al,[bp+4] ; sys_id
0000:0654 B4 06 mov ah,6 ;
0000:0656 3C 0E cmp al,0Eh ; sys_id = 0Eh?
0000:0658 74 11 je short loc_check13ext ; yes
0000:065A B4 0B mov ah,0Bh
0000:065C 3C 0C cmp al,0Ch ; sys_id = 0Ch?
0000:065E 74 05 je short loc_sysid0B0C ; yes
0000:0660 3A C4 cmp al,ah ; sys_id = 0Bh?
0000:0662 75 2B jne short loc_int13old ; no
0000:0664 40 inc ax ; chang zf to jump over check13ext
0000:0665 loc_sysid0B0C: ; sys_id = 0Bh, 0Ch, got here
0000:0665 C6 46 25 06 mov byte ptr [bp+25h],6 ; set boot record sector = 6
0000:0669 75 24 jnz short loc_int13old
0000:066B loc_check13ext: ; Function 41 (Check Extensions Present)
; In : AH -Int 13 function Number
; BX -55AAh
; DL -Drive
; Out: AL -Internal Use, not preserved
; AH -21h, Major version of these extensions
; BX -AA55h
; CX -Interface support bit map as follows,
; 0 Extended access functions.
; 1 Drive Locking and Ejecting
; 2 EDD Support
0000:066B BB 55AA mov bx,55AAh ; 3-15 Reserved, must be 0
0000:066E 50 push ax ; Carry flag Clear if INT 13h, FN 41h supported
0000:066F B4 41 mov ah,41h ; Check Extensions Present notifies the caller that
0000:0671 CD 13 int 13h ; Extended drive support is preset.
0000:0673 58 pop ax ; support int13 ext?
0000:0674 72 16 jc short loc_no13ext ; no
0000:0676 .81 FB AA55 cmp bx,0AA55h
0000:067A 75 10 jne short loc_no13ext
0000:067C F6 C1 01 test cl,1
0000:067F 74 0B jz short loc_no13ext
; yes
0000:0681 8A E0 mov ah,al ; change code to jump over old int 13
0000:0683 88 56 24 mov [bp+24h],dl ; drive
0000:0686 C7 06 06A1 1EEB mov word ptr ds:[6A1h],1EEBh; "jump short 06C1"
0000:068C loc_no13ext:
0000:068C 88 66 04 mov [bp+4],ah ; return from Function 41 (Check Extensions Present)
0000:068F loc_int13old: ; 0Bh,0Ch,0Eh, got here
0000:068F BF 000A mov di,0Ah ; retry count
0000:0692 loc_readin: ; read in boot record, xref 06B6, 06D8
0000:0692 B8 0201 mov ax,201h ; func ah=2 :read, al=1 :sector
0000:0695 8B DC mov bx,sp ; es:bx=7C00h :buffer
0000:0697 33 C9 xor cx,cx
0000:0699 83 FF 05 cmp di,5 ; retry 5 times still error ?
0000:069C 7F 03 jg short loc_readbackup ; no
; yes, read 2nd copy of boot record
0000:069E 8B 4E 25 mov cx,[bp+25h] ; ch=cyl, cl=sector
; jmp short loc_int13ext
0000:06A1 loc_readbackup: ; xref 069C
0000:06A1 03 4E 02 add cx,[bp+2] ; start_sector (bits 0-5)
0000:06A4 CD 13 int 13h ; Disk dl=drive ? ah=func 02h
; read sectors to memory es:bx
; al=#,ch=cyl,cl=sectr,dh=head
0000:06A6 loc_int13extback: ; go back from int13ext, xref 06CF
0000:06A6 72 29 jc short loc_retry
0000:06A8 BE 0746 mov si,offset msg3 ; 'Missing operating system'
0000:06AB 81 3E 7DFE AA55 cmp word ptr ds:[7DFEh],0AA55h; magic word valid?
0000:06B1 74 5A je short loc_gobootrecok ; yes, finished
; no
0000:06B3 83 EF 05 sub di,5 ; try backup of boot record if possible
0000:06B6 7F DA jg loc_readin
0000:06B8 loc_endofretry: ; end of retry, still error
; show error message, then halt
0000:06B8 85 F6 test si,si ; error msg in si?
0000:06BA 75 83 jnz loc_msg ; yes, go show
0000:06BC BE 0727 mov si,offset msg2 ; no, show 'Error loading operating system'
0000:06BF EB 8A jmp short loc_msgh
0000:06C1 loc_int13ext: ; xref 0686, 06A1
0000:06C1 98 cbw ; al=01 so ax=0001
0000:06C2 91 xchg cx,ax ; cx=0001
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -