admin 管理员组文章数量: 1184232
64位操作系统——bootLoader
作者:王赛宇
参考列表:
- 《一个64位操作系统的设计与实现》
- 《nasm用户手册》
- 各种博客
第一部分: 写一个简单的引导程序并且显示一些字符
org 0x7c00 ; 将程序加载到0x7c00位置,即:指定程序的起始地址
BaseOfStack equ 0x7c00
; 将CS寄存器的段基址设置到DS、ES、SS中
Label_Start:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, BaseOfStack
; ====== 清空屏幕
mov ax, 0600h
mov bx, 0700h
mov cx, 0
mov dx, 184fh
int 10h
; ===== set focus ??? 没看懂这是啥意思
mov ax, 0200h
mov bx, 0000h
mov dx, 0000h
int 10h
; ===== 在屏幕上显示:Start Booting......
mov ax, 1301h
mov bx, 000fh
mov dx, 0000h
mov cx, 10
push ax
mov ax, ds
mov es, ax
pop ax
mov bp, StartBootMessage
int 10h
; ===== 软盘驱动器复位
xor ah, ah
xor dl, dl
int 13h
jmp $
StartBootMessage: db "Start Boot"
;======= fill zero until whole sector
times 510 - ($ - $$) db 0
dw 0xaa55
这个程序可以被分为几个部分:
- 初始化部分: 定义了程序被加载到的地方,以及程序中的常量,并且对所有寄存器进行了简单的初始化
-
显示部分: 通过
int 10h的指令,进行了显示方面的一系列处理 - 软盘驱动器复位:这里我暂时也没搞明白是在干什么
- 填充部分
简单的汇编知识
在搞明白这些之前,我们需要先学一点简单的汇编:
我们会发现,上面的程序主要是在对一些寄存器进行简单的操作,这些寄存器是:
ax,bx,cx,dx
他们是nasm语言的通用寄存器。同时,这些寄存器可以根据高位、低位被划分成:
ah,al,bh,bl,ch,cl,dh,dl
,可以理解为:
ax = ah << 16 + al
也就是说
ax
是由
ah\al
两个部分拼接而成的。
理解了这一点之后,你往下看,暂时就没有太大的难度了。
int 指令
我们首先来看一下这里的
int
指令,学过组成原理的同学都知道,这里的int就是软件中断,我们这里用到了两种int指令,他们实际上就是调用了BIOS里面的一些固有程序,进行了一些我们期望中的处理,我们来看一下这些
int
分别做了哪些操作:
第一次
; ====== 清空屏幕
mov ax, 0600h
mov bx, 0700h
mov cx, 0
mov dx, 184fh
int 10h
这里设置了
ax = 0600h
,
bx=0700h
,
cx=0
,
dx=184fh
,然后调用了
int 10h
,
INT 10h
主要执行的是一些与显示相关的操作。我们来看一下这里的操作:
首先来看
ax
寄存器:我们经过划分可以知道:
ah = 0x06
,
al = 0x00
,这里的ah指示得是执行
INT 10h
相关程序中的哪种操作:当
ah = 0x06
时,执行的是
按指定范围滚动窗口的功能
。
具体的参数如下:
- AL=滚动的列数,若为0则实现清空屏幕功能;
- BH=滚动后空出位置放入的属性;
- CH=滚动范围的左上角坐标列号;
- CL=滚动范围的左上角坐标行号;
- DH=滚动范围的右下角坐标列号;
- DL=滚动范围的右下角坐标行号;
- BH=颜色属性。
- bit 0~2:字体颜色(0:黑,1:蓝,2:绿,3:青,4:红,5:紫,6:综,7:白)。
- bit 3:字体亮度(0:字体正常,1:字体高亮度)。
- bit 4~6:背景颜色(0:黑,1:蓝,2:绿,3:青,4:红,5:紫,6:综,7:白)。
- bit 7:字体闪烁(0:不闪烁,1:字体闪烁)。
这里我们将
AL
设置为了0, 所以实现的是清空屏幕的功能。
第二次
; ===== set focus ??? 没看懂这是啥意思
mov ax, 0200h
mov bx, 0000h
mov dx, 0000h
int 10h
这里作者给出的代码中写的是
set focus
,我们还是来看一下
ah
的值:
ah = 0x02
,
ah = 0x02
时
INT 10h
执行
屏幕光标位置的设置功能
。
- DH=游标的列数;
- DL=游标的行数;
- BH=页码。
第三次
; ===== 在屏幕上显示:Start Booting......
mov ax, 1301h
mov bx, 000fh
mov dx, 0000h
mov cx, 10
push ax
mov ax, ds
mov es, ax
pop ax
mov bp, StartBootMessage
int 10h
相信大家已经掌握了这套研究的方法了,我们直入主题: 这里执行的是显示字符串的方法,字符串存储在
StartBootMessage
位置,参数如下:
- AL=写入模式。
- AL=00h:字符串的属性由BL寄存器提供,而CX寄存器提供字符串长度(以B为单位),显示后光标位置不变,即显示前的光标位置。
- AL=01h:同AL=00h,但光标会移动至字符串尾端位置。
- AL=02h:字符串属性由每个字符后面紧跟的字节提供,故CX寄存器提供的字符串长度改成以Word为单位,显示后光标位置不变。
- AL=03h:同AL=02h,但光标会移动至字符串尾端位置。
- CX=字符串的长度。
- DH=游标的坐标行号。
- DL=游标的坐标列号。
- ES:BP=>要显示字符串的内存地址。
- BH=页码。
- BL=字符属性/颜色属性。
- bit 0~2:字体颜色(0:黑,1:蓝,2:绿,3:青,4:红,5:紫,6:综,7:白)。
- bit 3 :字体亮度(0:字体正常,1:字体高亮度)。
- bit 4~6:背景颜色(0:黑,1:蓝,2:绿,3:青,4:红,5:紫,6:综,7:白)。
- bit 7:字体闪烁(0:不闪烁,1:字体闪烁)
我们注意到这里执行的是光标移动到字符串尾端位置的写入模式,通过规定cx,规定了字符串的长度。我们尝试加长字符串的长度,但不更改cx会发生什么样的事情:我们将下面的
StartBootMessage
部分更改为:
StartBootMessage: db "01234567891011121314151617181920"
随后进行查看,结果如下:
版权声明:本文标题:64位BootLoader深度剖析:X64版操作手册 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1773476458a3562374.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论