📄 boot.asm.svn-base
字号:
;定义各中断数据扇区段,由段地址0000开始
data segment at 0h
;驱动器中断位置
org 13h*4
DiskInt dd ?
;保护的驱动器中断位置
org 50h*4
HDInt dd ?
org 3f0h
ProSeg dw ?
;保存记载内存大小位置
org 413h
memory_size dw ?
;引导扇区装入的地址
org 7c00h
Boot proc far
Boot endp
data ends
code segment
assume cs:code,ds:data
org 0h
Head:
jmp start
;保存久的INT13中断位置
RealInt label dword
RealOFF dw 0a189h
RealCS dw 0f000h
start:
cli
mov ax,cs ;AX=CX=0
mov dx,ax ;DS=AX=0
mov es,ax ;ES=AX=0
mov ss,ax ;SS=AX=0
mov sp,7c00h ;SP=7C00H
xor si,si ;SI=0
sti
dec [memory_size];将记载内存大小位置减少2K
dec [memory_size]
mov ax,[memory_size];AX=内存大小
mov cl,6
shl ax,cl ;算出启始的段地址
mov es,ax ;保存至es
mov di,0 ;DI=0
mov si,7c00h ;将0:7C00H开始的200BYTES移动到ES:O高端
mov cx,200h
rep movsb ;+++
push es
mov ax,offset continue
push ax ;跳到ES:CONTINUE
retf
continue:
xor ax,ax ;AX=0
mov ds,ax ;DS=0
mov [ProSeg],es ;ES保存到3f0h
cli
;保存原INT13中断位置到REALINT及INT 50H
mov ax,word ptr[DiskInt]
mov word ptr cs:[RealOFF],ax
mov word ptr[HDInt],ax
mov ax,word ptr[DiskInt+2]
mov word ptr cs:[RealCS],ax
mov word ptr[HDInt+2],ax
;设置新的驱动器中断位置
mov ax,offset Int_Handler
mov word ptr [DiskInt],ax
mov word ptr [DiskInt+2],cs
;读取指定扇区程序至ES:0200H
mov si,0002h ;读取次数为2
$ReadPass:
mov ax,0201h ;读取1个扇区
mov bx,0200h ;读取到ES:0200H
mov cx,0004h ;由第4扇区开始
mov dx,0080h
pushf ;模拟INT13H 中断
call dword ptr RealInt
jnb $1
dec si
jnz $ReadPass
$1: ;模拟CALL调用
mov ax,offset $j1
push ax
mov ax,0200h ;CALL-0200H
push ax
ret
$j1:
sti
xor ax,ax
mov es,ax
mov si,0002h
;读取原MBR到7C00H
$ReadBoot:
mov ax,0201h
mov bx,7c00h
mov cx,0003h
mov dx,0080h
pushf
call dword ptr RealInt
jnb $2
dec si
jnz $ReadBoot
$2:
jmp boot
Int_Handler:
sti
cmp dx,0080h ;若读取MBR将自动读取第3扇区
jne Check
cmp cx,0001h
jne Check
mov cx,0003h
Conti:
jmp cs:[RealInt]
Check:
cmp dx,0080h ;若不为C盘则继续(C盘不允许操作)
jz Error
jmp conti
Error:
mov ah,03h
stc
retf 2
Tail:
Filler_Amount equ 512-(Tail-Head)-2 ;计算机代码占用空间大小
db Filler_Amount dup(0)
dw 0aa55h
code ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -