bootsect.s引导扇区代码
寄存器知识
寄存器名称 | 用处 | 对应偏移 | 备注 |
---|---|---|---|
CS(代码段寄存器) | 存放代码 | IP | 基地cs:偏移地址ip |
DS(数据段寄存器) | 存放数据 | SI | |
SS(栈段寄存器) | 作为栈使用 | SP | ss相当于堆栈段的首地址,sp相当于堆栈段的偏移地址 |
ES(扩展段寄存器) | DI |
代码第一片段:
/* BOOTSEG = 0x07c0
INITSEG = 0x9000
SETUPSEG = 0x9020
*/
start:
mov ax, #BOOTSEG mov ds, ax
mov ax, #INITSEG mov es, ax
mov cx, #256
sub si, si sub di, di
rep movw
jmpi go, INITSEG
下面将逐行解释代码:
mov ax, #BOOTSEG mov ds, ax
ds=0x07c0
mov ax, #INITSEG mov es, ax
es=0x9000
mov cx, #256
cx=256, #表示立即寻址,256单位为字,即512个字节
sub si, si sub di, di
si=0,di=0
rep movw
rep:重复执行该语句直至寄存器cx为0
movw:将DS:SI的内容送至ES:DI(拷贝)
jmpi go, INITSEG
jmpi:段间跳转指令,执行完该条指令后,CS = INITSEG=0x9000,IP = go
代码第二片段(只读关键):
go:mov ax, cs
mov ds, ax mov es, ax mov ss, ax mov sp, #0xff00
load_setup:
mov dx, #0x0000 mov cx, #0x0002 mov bx, #0x0200
mov ax, #0x0200+SETUPLEN int 0x13
jnc ok_load_setup
mov dx, #0x0000
mov ax, #0x0000
int 0x13
j load_setup
int 0x13表示BIOS读磁盘扇区的中断:ah=0x02-都磁盘,al=扇区数量(SETUPLEN=4,表示读四个扇区),ch=柱面号,cl=开始扇区(从第二个扇区开始,boot扇区是第一个扇区),dh=磁头号,dl=驱动器号,es:bx=内存地址(9000:0200,即90000+200=90200)
Ok_load_setup: //载入setup模块
mov dl,#0x00 mov ax,#0x0800 //ah=8获得磁盘参数
int 0x13 mov ch,#0x00 mov sectors,cx
mov ah,#0x03 xor bh,bh int 0x10 //读光标
mov cx,#24 mov bx,#0x0007
mov bp,#msg1 mov ax,#1301 int 0x10 //显示字符
mov ax,#SYSSEG //SYSSEG=0x1000
mov es,ax
call read_it //读入system模块
jmpi 0,SETUPSEG
bootsect.s中的数据//在文件末尾
sectors: .word 0 //磁道扇区数
msg1:.byte 13,10
.ascii “Loading system...”
.byte 13,10,13,10
mov bp,#msg1指出要显示的内容的地址
如果要修改成显示“Loading system…”字样,那么需要修改mov cx,#24中的24(cx,#24表示需要输出24个字符)
引导扇区的末尾
.org 510
.word 0xAA55 //扇区的最后两个字节
之后就可以转入setup执行了。即
jmpi 0, SETUPSEG
BIOS的作用
- 自诊断程序:通过读取CMOS RAM中的内容识别硬件配置,并对其进行自检和初始化;
- CMOS设置程序:引导过程中,用特殊热键启动,进行设置后,存入CMOS RAM中;
- 系统自举装载程序:在自检成功后将磁盘相对0道0扇区上的引导程序装入内存,让其运行以装入DOS系统;
- 主要I/O设备的驱动程序和中断服务
总结
总结打开电源后都做了什么?
- x86 PC刚开机时CPU处于实模式
- 开机时,CS=0xFFFF;IP=0x0000
- 寻址0xFFFF0(ROM BIOS映射区)
- 检查RAM,键盘,显示器,软硬磁盘
- 将磁盘0磁道0扇区读入0x7c00处,0x7c00处的代码就是从磁盘引导扇区读入的那512个字节
- 设置CS=0x07c0,IP=0x0000,开始执行bootsect.s