上一个版本的boot在显示了一串字符后就进入了死循环。
操作系统的定义是一个架设在硬件层和用户层的管理软件,我必须扩展boot使它逐步接近意义上的操作系统。
ibm-pc兼容系列的电脑在启动时载入从软盘的0磁道开始的512个字节,放入0x7c00的内存,然后从那里开始执行。
你的操作系统不可能才512个字节吧!为此我们在执行这512个字节的程序里必须加入
- 载入另一个位置上的n个字节的程序放到一个规定好的内存里
- 在执行到512字节前作一个跳转,来到那个规定好的内存的开头继续执行
下面是改造后的boot.asm
;; 文件:boot.asm
;; 作用:从7c00h处启动,显示载入系统信息"loading system..."
;; 没有文件系统,1.44m 512bits/80sec 软盘启动,
;; 创建日期:2004/01/30 flyback
;; fly-back@163.com
;; ===================================
;; 作用:从7c00h处启动,显示载入系统信息"loading system..."
;; 没有文件系统,1.44m 512bits/80sec 软盘启动,
;; 创建日期:2004/01/30 flyback
;; fly-back@163.com
;; ===================================
org 7c00h ; 启动入口地址
main:
jmp start ; 跳转到开始程序入口
main:
jmp start ; 跳转到开始程序入口
.loadmsg db 'loading system...',0 ; 要显示的字符窜以0结尾
.loadfail db 'load init failure!',0 ; 载入失败信息
%define loadpoint 9000h ; 载入点,初始化程序载入到9000h的地方
%define loadoffset 0000h
start:
cli ; 关中断,防止意外中断打断程序执行
mov ax, cs ;
mov ds, ax ; 设置数据段
mov es, ax ;
xor ax, ax ; 设置堆栈段
mov ss, ax
mov sp, 0ffffh ; 7c00以前为堆栈入口
mov ss, ax
mov sp, 0ffffh ; 7c00以前为堆栈入口
sti ; 开中断
mov si, main.loadmsg ; 调用显示载入信息
call pntchr
; jmp $ ; 死循环
call pntchr
; jmp $ ; 死循环
; 读取在200h(512)字节后400h字节前的数据放入载入点(9000h)处 es:bx
; 读取软盘,调用bios 13h中断功能
; 复位
mov ah, 00h
mov dl, 0h
int 13h
; 读取软盘,调用bios 13h中断功能
; 复位
mov ah, 00h
mov dl, 0h
int 13h
mov ax, loadpoint
mov es, ax
mov bx, loadoffset
loadfloppy:
mov ah, 0x02 ; bios 读取扇区命令
mov al, 0x01 ; 读取一个扇区
mov ch, 0h ; 起始磁道 0
mov cl, 2h ; 起始扇区 第二扇区
mov dh, 0h ; 磁头号 1
mov dl, 0h ; 驱动器号 0 a:
int 13h ;
mov es, ax
mov bx, loadoffset
loadfloppy:
mov ah, 0x02 ; bios 读取扇区命令
mov al, 0x01 ; 读取一个扇区
mov ch, 0h ; 起始磁道 0
mov cl, 2h ; 起始扇区 第二扇区
mov dh, 0h ; 磁头号 1
mov dl, 0h ; 驱动器号 0 a:
int 13h ;
jc failure ; 失败显示失败信息
jmp loadpoint:loadoffset
failure:
lea si, [main.loadfail]
call pntchr
hlt
jmp loadpoint:loadoffset
failure:
lea si, [main.loadfail]
call pntchr
hlt
;----------------显示字符串----------------------
pntchr:
lodsb ; 从ds:si装载一个字符到al
or al,al ;
jz endpntchr ; 如果 al = 0, 返回
;
mov ah,0x0e ;
mov bx,0x0007 ;
int 0x10 ; 调用bios中断显示字符
jmp pntchr ;
;
endpntchr: ;
ret ; 返回
pntchr:
lodsb ; 从ds:si装载一个字符到al
or al,al ;
jz endpntchr ; 如果 al = 0, 返回
;
mov ah,0x0e ;
mov bx,0x0007 ;
int 0x10 ; 调用bios中断显示字符
jmp pntchr ;
;
endpntchr: ;
ret ; 返回
;--------------------------------------------------
times 512-($-$$) db 0 ; 保证boot区有512个字节
; dw 0aa55h ; boot区标记
times 512-($-$$) db 0 ; 保证boot区有512个字节
; dw 0aa55h ; boot区标记
镜像文件boot.img现在有512个字节,我们还需要在它的后面无缝连接一段用来被boot程序载入的200h~400h程序(大小200h)
;; 文件:other.asm
;; 作用:一个显示字符的后继程序
;; 创建日期:2004/01/30 flyback
;; fly-back@163.com
;; ===================================
start2:
; 清除屏幕
mov ax, cs
mov ds, ax
mov es, ax
;; 作用:一个显示字符的后继程序
;; 创建日期:2004/01/30 flyback
;; fly-back@163.com
;; ===================================
start2:
; 清除屏幕
mov ax, cs
mov ds, ax
mov es, ax
mov si, start2msg
call pntchr2
jmp $
call pntchr2
jmp $