能力值:
( LV13,RANK:330 )
|
-
-
2 楼
; LDMBR.ASM 启动代码功能:
; (1) 根据用户输入的分区索引号,把对应的操作系统的原MBR内容装入内存的0000:7c00处;
; (2) 检测硬盘分区表变动,根据需要决定是否修改LDMBR分区信息并保存;
; (3) 将控制权还给原MBR启动代码.
; (4) 内含默认MBR启动代码,以便在没有可引导的MBR时使用.
; (5) 支持DOS下直接远行LDMBR引导MBR.
; (6) LDMBR添加代码自动定位功能,一次编译无需修改
; 一般情况零道零面,除BootSector(启动扇区),也就是硬盘的第一个扇区,存在重要数据
; 包括MBR,DPT,BRID三部分. 其余的62个扇区全部为空闲,每磁道最大扇区数为63.
.386
.model tiny
code segment byte public 'CODE' use16
assume cs:code,ds:code
org 100h
start:
call begin
db 'HSQ' ;检测标志
begin:
cli ;关中断
pop ax
sub ax, 3 ;ax=7C00 (DOS下不可能,需重定位)
mov sp, ax ;SP=7C00
mov bp, ax ;bp保存入口基址,为字符串寻址参照值
push cs
push cs
push cs
pop ds ;DS=0 (DOS下不可能,需重定位)
pop ss ;SS=0
pop es ;ES=0
sti ;中断允许
push ax ;ax为入口基址,保存作为字符串寻址参照值
mov bx, ax ;bx保存,重定位标志
add bx, 200h
mov cx, 02h
mov ax, 020Ah ;es=0000h bx=7c00+200h
mov dx, 80h
int 13h ;将硬盘0道0面2扇区读入10个扇区0000:7c00处后
pop bx ;保存入口基址 bx
call ShowAuthorInformation ;输出版权信息
mov ax, 1000h
mov es, ax
mov di, bx
add di, offset next - 100h ;剔除已经执行部分
push ax
push di ;指向目的地址
mov si, bx ;设置源地址 ds:si
mov di, bx ;设置目的地址 es:di,di=es(保证偏移相同)
mov cx, offset mbr_end - 100h ;设置 cx 为传输长度
cld ;设置正向传输
rep movsb ;把启动代码搬到1000::offset next处
retf ;跳转到1000:next处
next:
push ds
push es
pop ds ;ds=1000h
pop ax ;es=0000h
test ax, ax
je normalboot
xor ax, ax ;确保DOS下也能顺利装在原MBR到0000:7c00处
mov bx, 7c00h
normalboot:
mov es, ax
call ClearScreen ;清屏
push bx
mov bx, offset folengthtable - 100h
add bx, bp
mov di, offset fouctiontable - 100h
add di, bp ;字符串寻址参照值
showtitle:
mov si, [di]
add si, bp
mov cx, [bx]
call dbgprint ;显示功能信息
add di, 2
add bx, 2
cmp word ptr [di], 0
jne showtitle
pop bx
mov si, offset msg_01 - 100h
add si, bp ;字符串寻址参照值
mov cx, msg_01_len
call dbgprint ;显示输入提示信息
read:
xor ah, ah
int 16h ;从键盘读字符
cmp al, '1'
jb read
cmp al, '9'
ja read ;检查字符的合法性
and al, 0fh ;将高四位清零
add al, 0ah ;前10个扇区默认备MBR占用
mov cl, al ;设置扇区号: 用户输入值
xor ch, ch ;设置磁道号: 0
rmbr:
mov ax, 0201h ;es=0000h bx=7c00
mov dx, 80h
int 13h ;将硬盘0道0面指定扇区读入0000:7c00处
cmp word ptr es:[bx].1feh, 0AA55h ;检验引导区是否合法
je loadDPT
mov si, offset msg_02 - 100h
add si, bp
mov cx, msg_02_len
call dbgprint ;显示出错信息提示信息
mov ah, 1h
mov ch, 10h
mov cl, 0
int 10h ;关闭光标
xor ah, ah
int 16h ;暂停
reboot:
xor ax, ax
mov bx, ax
dec ax
mov es, ax ;设置重启PC
loadmbr:
call ClearScreen
xor ax, ax
mov ss, ax
mov sp, bx
mov bp, sp
push es
push bx
retf ;将控制权还给原MBR启动代码
loadDPT:
push es ;es=0000
push ds ;ds=1000
pop es ;es=1000
pop ds ;ds=0000
lea si, [bx+1BEh] ;bx=7c00
;设置源地址 ds:si=0000:7DBEh
lea di, [bp+1BEh] ;设置目的地址 es:di=1000:7DBEh
mov cx, 40h ;10h*4
push si
push di
repe cmpsb ;检测是否有必要修改分区表
pop di
pop si
test cx, cx
je same_DPT
push si
mov ax, es
push ds
mov ds, ax
mov si, offset msg_03 - 100h
add si, bp
mov cx, msg_03_len
call dbgprint ;显示修改分区表提示信息
pop ds
pop si
reread:
xor ah, ah
int 16h ;从键盘读字符(等待用户确认)
cmp al, 'n'
je same_DPT
cmp al, 'N'
je same_DPT
cmp al, 'y'
je upate_DPT
cmp al, 'Y'
jne reread
upate_DPT:
mov cx, 40h
rep movsb
xchg bx, bp ;bx=7c00, bp=0100
mov ax, 0301h ;es=1000, bx=(0100)7c00
mov cx, 01h
int 13h ;修改并保存分区信息
xchg bx, bp
jmp reboot ;重启兼容实际CMOS程序(在VMware中可以不重启)
cmp bx, bp ;检测DOS还是启动模式
jz reboot
same_DPT:
push ds ;ds=0000
pop es ;es=0000
jmp loadmbr ;将控制权还给原MBR启动代码
;未了稳定和兼容,MBR启动扇区只使用1BEH个字节,防止覆盖DPT和BRID
currentcodelen = $ - start
leavecodelen = 1beh - currentcodelen ;对齐LDMBR
db 40h + leavecodelen dup(?),55h,0AAh
;*******************************以下为程序所需的数据*******************************
yyy equ 8 ;上边框行值
xxx equ 60 ;边框长度减二
color dw 5fh ;字符串颜色值
gtable dw g1-100h,g2-100h,g3-100h,g4-100h,g5-100h,g6-100h,g7-100h,g8-100h,\
g9-100h,0
fouctiontable dw fouction_00-100h,fouction_01-100h,fouction_02-100h,fouction_03-100h,\
fouction_04-100h,0
folengthtable dw fouction_01-fouction_00,fouction_02-fouction_01,fouction_03-fouction_02,\
fouction_04-fouction_03,msg_01-fouction_04
chartable dw char00a-100h,char00b-100h,char00c-100h,char01-100h,char02-100h,0
lengthtable dw char00b-char00a,char00c-char00b,char01-char00c,char02-char01,\
fouction_00-char02
g1 db 201,xxx dup(205),187
g2 db 186,xxx dup(' '),186
g3 db 186,xxx dup(' '),186
g4 db 186,xxx dup(' '),186
g5 db 204,xxx dup(205),185
g6 db 186,xxx dup(' '),186
g7 db 199,xxx dup(196),182
g8 db 186,xxx dup(' '),186
g9 db 200,xxx dup(205),188 ;画边框数据
gg equ $-g9 ;边框长度
xx equ (80-gg)/2 ;让边框水平居中显示
char00a db 'SoftWare Version Information 1.01 Compiled By Huang Shiquan'
char00b db 'Break Hard Disk Saving Card Program'
char00c db 'This program is used to break the hard disk saving card'
char01 db 219,219,219,178,178,177,177,176,176, ,\
'HD Anti-Virus & Security System', ,176,176,177,177,178,178,3 dup (219)
char02 db '(C)opyRight HSQ persion program company 2007.10.06'
fouction_00 db 'Muility Opertation System Loader V1.25',0dh,0ah,0dh,0ah
fouction_01 db '1.) Seclect One Opertation System For Loading',0dh,0ah
fouction_02 db '2.) Set A Default Opertation System For Loading',0dh,0ah
fouction_03 db '3.) Loading Mini DOS Opertation System By Huang Shiquan',0dh,0ah
fouction_04 db '4.) Remove This Muility Opertation System Loader Program',0dh,0ah
msg_01 db 0dh,0ah,'Enter sector index (1-9) to load operation system :'
msg_01_len = $ - msg_01
msg_02 db 0dh,0ah,0dh,0ah,4 dup(20h),'Sorry, cant load MBR becuase its invalid.Recommend information for you:',\
0dh,0ah,'If this problem continue, please change another sector index to try again and ',\
0dh,0ah,'maybe solve this problem Now, Press any key to restart your PC'
msg_02_len = $ - msg_02
msg_03 db 0dh,0ah,0dh,0ah,4 dup(20h),'Warning, The Disk Partition Table will be replace, are you sure to do this',\
0dh,0ah,'Sure(Y), Cancel (N) ? :'
msg_03_len = $ - msg_03
;*******************************以下为应用子程序*******************************
ClearScreen:
pusha
mov ax, 0600h
mov bh, 7
mov cx, 0
mov dx, 184fh
int 10h ;清屏
mov dx, 0
mov ax, 2
int 10h ;置光标在首位
popa
ret
dbgprint:
push ax
push bx
mov bx, 07h
mov ah, 0eh
show_continue:
mov al, [si]
int 10h
inc si
loop show_continue ;显示输入提示信息
pop bx
pop ax
ret
ShowAuthorInformation:
pusha
push cs
pop es
mov ax, 3 ;显示版本信息
int 10h ;置彩色文本方式80*25*16色
mov ah, 1h
mov ch, 10h
mov cl, 0
int 10h ;关闭光标
mov si, offset gtable -100h
add si, bx ;bx为入口基址
mov dh, yyy ;起始行
show_frame:
push si
mov bp, [si]
add bp, bx ;待处理串
pop si
mov dl, xx ;起始列
mov cx, gg ;串长度
push bx
mov bx, 005fh
mov ax, 1301h
int 10h ;BIOS中断调用
pop bx
inc dh
add si, 2
cmp word ptr [si], 0
jne show_frame ;显示边框
mov si, offset chartable -100h
add si, bx
mov di, offset lengthtable -100h
add di, bx
mov ax, 1301h ;显示字符串,光标返回起始位
mov dh, yyy+1 ;起始行
show_infromation:
push si
mov bp, [si]
add bp, bx ;待处理串
pop si
push bx
mov cx, [di] ;串长度
mov bx, 80
sub bx, cx
shr bx, 1
mov dl, bl ;让字符串水平居中显示
mov bx, 005fh
mov ax, 1301h
int 10h
pop bx
cmp dh, yyy+3
jbe normal_addnum
inc dh
normal_addnum:
inc dh
add si, 2
add di, 2
cmp word ptr [si], 0
jne show_infromation ;显示字符串
xor ah, ah
int 16h ;从键盘读字符
mov ah, 01h
mov ch, 0
int 10h ;打开光标
popa
ret
mbr_end:
code ends
end start
讨论: 当修改分区表后,在VMware中可以不重启而直接引导相应系统;可是在实际PC机上却行不通.每次当我试着跟踪,进入到到实际的OS引导代码部分一段距离时,系统就会僵死,没法继续了.不知那位知道其原由,还望赐教.
三.效果截图和相关源码
具体使用方法我就不说了,描述起来很麻烦的,能够看懂代码的应该就知道怎么用.我就是用这个来引导WINDOWS和LINUX以及自己的系统
代码一帖出来,都乱了 ,我也懒得慢慢调整, 不过附件中的源码是很工整的
|