1:功能
系统开机后,从0xFFFF0处(ROM)取出第一条指令开始执行,进行BIOS自检,检查正常后就用BIOS的输入功能将启动磁盘上的bootset.s读入内存0X7C00处,然后将自己移动到0X90000处。
该段程序的主要作用就是:
1)将setup加载到bootset后,0X90200处
2)调用int 0X10中断,输出屏幕信息:“Loading system…”
3)将system模块加载到内存0X10000处
4)跳到setup执行setup程序
2:代码实现
2.1:将自己从0X7C00移动到0X90000
BOOTSEG = 0x07c0 ! original address of boot-sector
INITSEG = 0x9000 ! we move boot here - out of the way
_start:
mov ax,#BOOTSEG //设置ds段接触器为0X7C0
mov ds,ax
mov ax,#INITSEG //设置es段接触器为0X9000
mov es,ax
mov cx,#256 //设置移动数值
sub si,si //源地址 ds:si = 0X7C0:0X0000
sub di,di //目的地址 es:di = 0X9000:0X0000
rep
movw
jmpi go,INITSEG //跳转到0X90000处(INIESEG为段地址)
2.2:读取setup,加载到0X90200处
go: mov ax,cs //将ds,es,ss都设置为移动后代码的段处(0x900)
mov ds,ax
mov es,ax
mov ss,ax
mov sp,#0xFF00 ! arbitrary value >>512 //设置堆栈指针
! load the setup-sectors directly after the bootblock.
! Note that 'es' is already set up.
//利用BIOS的中断0X13将setup模块,从第二扇区开始读到0X90200处,共读四个扇区
load_setup:
mov dx,#0x0000 ! drive 0, head 0
mov cx,#0x0002 ! sector 2, track 0
mov bx,#0x0200 ! address = 512, in INITSEG
mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors
int 0x13 ! read it
jnc ok_load_setup ! ok - continue
mov dx,#0x0000
mov ax,#0x0000 ! reset the diskette
int 0x13
j load_setup
2.3:输出屏幕信息:“Loading system…”
! Print some inane message
mov ah,#0x03 ! read cursor pos
xor bh,bh //读光标的位置
int 0x10
mov cx,#24 //总共24个字符
mov bx,#0x0007 ! page 0, attribute 7 (normal)
mov bp,#msg1 //指向要显示的字符串
mov ax,#0x1301 ! write string, move cursor
int 0x10 //写字符串并移动光标
.........
msg1: //字符串信息
.byte 13,10 //回车,换行的ASCII码
.ascii "Loading system ..."
.byte 13,10,13,10 //共24个字符
2.4:将system模块加载到内存0X10000处
ok, we've written the message, now
! we want to load the system (at 0x10000)
mov ax,#SYSSEG
mov es,ax ! segment of 0x010000
call read_it //读磁盘上的system模块,es为输入参数
call kill_motor
2.5:跳到setup,执行setup程序
!after that (everyting loaded), we jump to the setup-routine loaded directly after
!the bootblock:
jmpi 0,SETUPSEG //跳转到0X90200处,执行setup代码