1、IPL (Initial Program Loader,启动程序装载器)
2、软盘物理介绍
柱面80个,2个磁头,18个扇区,每个扇区512字节,软盘容量:80*2*18*512=1474560byte=1440kb
3、读取软盘数据到内存中去
CYLS EQU 10 ; 10个柱面
ORG 0x7c00 ; 起始程序在内存中的初始地址
JMP entry
DB 0x90
DB "HARIBOTE"
DW 512
DB 1
DW 1
DB 2
DW 224
DW 2880
DB 0xf0
DW 9
DW 18
DW 2
DD 0
DD 2880
DB 0,0,0x29
DD 0xffffffff
DB "HARIBOTEOS "
DB "FAT12 "
RESB 18
entry:
MOV AX,0 ; 对寄存器进行初始化
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
MOV AX,0x0820
MOV ES,AX ;在段寄存器中存地址时,实际地址=段寄存器*16
MOV CH,0 ; 柱面0
MOV DH,0 ; 磁头0
MOV CL,2 ; 扇区2
readloop:
MOV SI,0 ;
retry:
MOV AH,0x02 ; AH=0x02 :读入磁盘
MOV AL,1 ; 读1个扇区
MOV BX,0
MOV DL,0x00 ; 使用A磁盘驱动器
INT 0x13 ; 调用磁盘BIOS
JNC next ; 没出错时跳到next
ADD SI,1 ; SI加1
CMP SI,5 ;
JAE error ; SI >= 5 时跳转到Error
MOV AH,0x00
MOV DL,0x00 ;
INT 0x13 ; 重置驱动器
JMP retry
next:
MOV AX,ES
ADD AX,0x020
MOV ES,AX ; ADD ES,0x0200 ‚内存地址向下移动512个字节
ADD CL,1 ; 指向下一个扇区
CMP CL,18 ; 是不是到了第18个扇区
JBE readloop ; CL <= 18时,跳转到readloop
MOV CL,1 ;指向第一个扇区
ADD DH,1 ;磁头+1
CMP DH,2 ;磁头是否大于2
JB readloop ; DH < 2时,跳转到readloop
MOV DH,0 ;是0号磁头
ADD CH,1 ;柱面数量加1
CMP CH,CYLS
JB readloop ; CH < CYLS 时,跳转到readloop
fin:
HLT ; CPU处于休眠状态,鼠标键盘按下会被唤醒
JMP fin ;
error:
MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI,1 ; SI加1
CMP AL,0
JE fin
MOV AH,0x0e ; 读入磁盘
MOV BX,15 ;
INT 0x10 ; 中断
JMP putloop
msg:
DB 0x0a, 0x0a ; 换两行
DB "load error"
DB 0x0a ; 换行
DB 0
RESB 0x7dfe-$ ; 剩余的设为0
DB 0x55, 0xaa
1、遇到的难理解问题:代码显示只添加了0x020,转成10进制就是32个数,为什么说是下移动了512个地址。
MOV AX,ES
ADD AX,0x020
MOV ES,AX
原因:ES等段地址在表示实际内存地址时要乘以16。从0x820到0x840表示的实际地址是0x8200到0x8400,所跨区间是2*16*16=512。
2、书中说启动区地址是0x7c00-0x7dff这512个字节,但又说0x8000-0x81ff是启动项。很让人困惑,百度查询的结果:
电脑开机,计算机会将映像文件的第一个扇区内容拷贝至0x7c00-0x7dff,并且与此同时,会自动拷贝启动区0x7c00-0x7dff的映射到0x8000-0x81ff,所以说0x8000-0x81ff这一区域是属于启动区的
3、用C语言代替汇编语言(案例看的云里雾里)。