荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: autodotcom (cpu8086), 信区: Linux
标  题: neck(想了解主引导记录)看过来。
发信站: 荔园晨风BBS站 (Wed Apr  3 14:08:49 2002), 转信

觉得很不错,所以推荐给neck。




发信人: starw (孤星), 信区: Linux
标  题: MBR代码分析
发信站: BBS 水木清华站
西西,很早以前的东东了,都不太记得了,有什么错误和不足欢迎大家指出

机器加电或按reset键后都要进行系统复位,复位后CS=FFFFH,IP=0000H
那么自然就从FFFF:0000H处开始执行指令,这个地方只有一条JMP指令
跳转到系统自检程序处,系统自检完成后把软盘的第一个扇区(如果由软盘启动)

或者硬盘的第一个扇区,即MBR扇区(如果由硬盘启动)读入到0:7C00H处
然后把控制权交出,从0:7C00H处继续执行,下面就是硬盘的MBR代码分析
其中的引导扇区是指硬盘相应分区的第一个扇区,是和操作系统有关的
操作系统的引导是由它来完成的,而MBR并不负责,MBR和操作系统无关
他的任务是把控制权转交给操作系统的引导程序

程序流程:

1 将程序代码由0:7C00H移动到0:0600H(注,BIOS把MBR放在0:7C00H处)
2 搜索可引导分区,即80H标志
    成功:goto 3
    失败:跳入ROM BASIC
    无效分区表:goto 5
3 读引导扇区
    失败:goto 5
    成功:goto 4
4 验证引导扇区最后是否为55AAH
    失败:goto 5
    成功:goto 6
5 打印错误进入无穷循环
6 跳到0:7C00H进行下一步启动工作

下面将用汇编语言写出这一段代码,并进行说明。

;MBR.ASM
;       MASM MBR
;       LINK MBR
;       EXE2BIN MBR

        .MODEL tiny
        .CODE

;设置寄存器及堆栈值

        org 0
Head:
Start:
        cli
        xor ax,ax
        mov ss,ax
        mov sp,7C00H    ;ss:sp=0:7C00H
        mov si,sp
        push ax
        pop es
        push ax
        pop ds          ;es=ds=0
        sti

;将程序代码由0:7C00H移动到0:0600H处

        cld
        mov di,600H
        mov cx,100H     ;100H Words=512 Bytes,即一个扇区大小
        repne movsw
        db 0EAH         ;这个是FAR JUMP的机器码
        dw offset Continue+600H, 0000H  ;这个是跳转目的地址,即0:061DH

;搜索可引导分区

Continue:

        mov si,600H+1BEH        ;si指向分区表
        mov bl,4                ;四个分区

FindBoot:

        cmp byte ptr[si],80H
        je SaveRec              ;读扇区位置
        cmp byte ptr[si],0
        jne Invaild             ;无效分区
        add si,10H
        dec bl
        jnz FindBoot
        int 18H                 ;进入ROM BASIC

;读取引导分区的扇区,柱面号

SaveRec:

        mov dx,[si]
        mov cx,[si+2]
        mov bp,si

;检查其余分区表

FindNext:

        add si,10H
        dec bl
        jz SetRead
        cmp byte ptr[si],0      ;是否存在非法分区
        je FindNext

Invaild:

        mov si,offset ErrMsg1+600H

;字符串输出子程序

PrintStr:

        lodsb
        cmp al,0
        je DeadLock
        push si
        mov bx,7
        mov ah,0EH              ;输出字符
        int 10H
        pop si
        jmp short PrintStr      ;下一字符

DeadLock:

        jmp short DeadLock      ;无穷循环,也可以写成jmp $

;读引导扇区

SetRead:

        mov di,5                ;读取次数

ReadBoot:

        mov bx,7C00H
        mov ax,201H
        push di
        int 13H                 ;cx,dx已经在SaveRec处得到
        pop di
        jnc GoBoot              ;成功则启动
        xor ax,ax
        int 13H                 ;reset驱动器,然后再读取
        dec di
        jnz ReadBoot

        mov si,offset ErrMsg2+600H
        jmp short PrintStr      失败输出信息,并进入无穷循环

;检查读入的引导扇区

GoBoot:

        mov si,offsetErrMsg3+600H
        mov di,7C00H+1FEH
        cmp word ptr[di],0AA55H
        jne PrintStr            ;非AA55标志则输出错误信息
        mov si,bp               ;si指向可启动分区
        db 0EAH,0,7CH,0,0       ;跳转至0:7C00H

ErrMsg1 db      'Invaild partition table',0
ErrMsg2 db      'Error loading operating system',0
ErrMsg3 db      'Missing operating system',0

Tail:

FillNum equ     1BEH-(Tail-Head)        ;计算填0数目
        db FillNum dup(0)

;四个分区表项数据,跟分区情况有关,详细含义另解

PartTable db 80H,1,1,0,4,4,0D1H,2,11H,0,0,0,0FEH,0FFH,0,0
          db 0,0,0C1H,3,5,4,0D1H,0FEH,0FFH,0FFH,0,0,0ACH,53H,0,0
          db 20H dup(0)

ID      dw 0AA55H

        end start

;如果开始试用org 600H,那么访问数据时就不必加上600H,如mov si,offset
ErrMsg2+600H
;可写为mov si,offset ErrMsg2,这时就不能用exe2bin得到数据,必须试用
debug
;debug mbr.exe
;-nmbr.bin
;-rcx 200
;-wcs:600
;-q

--
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.55.48]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店