30天自制操作系统
上QQ阅读APP看书,第一时间看更新

4 加工润色

刚才我们把程序变成了短短的22行,这成果令人欣喜。不过还有一点不足就是很难看出这些程序是干什么的,所以我们下面就来稍微改写一下,让别人也能看懂。改写后的源文件增加到了48行,它位于附带光盘的projects\01_day\helloos2目录下,大家可以直接把helloos2文件夹复制到tolset里。现在helloos1也可以删掉了(每个文件夹都是独立的,用完之后就可以删除,以后不再赘述。当然放在那里留作纪念也是可以的)。

现在的程序有50行,也占不了多少地方,所以我们将它写在下面了。

有模有样的源代码

; hello-os
; TAB=4

; 以下这段是标准FAT12格式软盘专用的代码

        DB    0xeb, 0x4e, 0x90
        DB    "HELLOIPL"      ; 启动区的名称可以是任意的字符串(8字节)
        DW    512              ; 每个扇区(sector)的大小(必须为512字节)
        DB    1                ; 簇(cluster)的大小(必须为1个扇区)
        DW    1          ; FAT的起始位置(一般从第一个扇区开始)
        DB    2          ; FAT的个数(必须为2)
        DW    224       ; 根目录的大小(一般设成224项)
        DW    2880      ; 该磁盘的大小(必须是2880扇区)
        DB    0xf0      ; 磁盘的种类(必须是0xf0)
        DW    9          ; FAT的长度(必须是9扇区)
        DW    18         ; 1个磁道(track)有几个扇区(必须是18)
        DW    2          ; 磁头数(必须是2)
        DD    0          ; 不使用分区,必须是0
        DD    2880      ; 重写一次磁盘大小
        DB    0,0,0x29        ; 意义不明,固定
        DD    0xffffffff      ;(可能是)卷标号码
        DB    "HELLO-OS   "   ; 磁盘的名称(11字节)
        DB    "FAT12   "      ; 磁盘格式名称(8字节)
        RESB  18               ; 先空出18字节

; 程序主体
        DB    0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
        DB    0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
        DB    0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
        DB    0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb
        DB    0xee, 0xf4, 0xeb, 0xfd

; 信息显示部分

        DB    0x0a, 0x0a      ; 2个换行
        DB    "hello, world"
        DB    0x0a             ; 换行
        DB    0

        RESB  0x1fe-$         ; 填写0x00,直到 0x001fe
        DB    0x55, 0xaa

; 以下是启动区以外部分的输出

        DB    0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
        RESB  4600
        DB    0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
        RESB  1469432

■■■■■

这里有几点新内容,我们逐一来看一下。首先是“; ”命令,这是个注释命令,相当于C语言或是C++中的“//”。正是因为有它,我们才可以在源代码里加入很多注释。

其次是DB指令的新用法。我们居然可以直接用它写字符串。在写字符串的时候,汇编语言会自动地查找字符串中每一个字符所对应的编码,然后把它们一个字节一个字节地排列起来。这个功能非常方便,也就是说,当我们想要变更输出信息的时候,就再也不用自己去查字符编码表了。

再有就是DW指令和DD指令,它们分别是“define word”和“define double-word”的缩写,是DB指令的“堂兄弟”。word的本意是“单词”,但在计算机汇编语言的世界里,word指的是“16位”的意思,也就是2个字节。“double-word”是“32位”的意思,也就是4个字节。

对了,差点忘记说RESB 0x1fe-$了。这个美元符号的意思如果不讲,恐怕谁也搞不明白,它是一个变量,可以告诉我们这一行现在的字节数(如果严格来说,有时候它还会有别的意思,关于这一点我们明天再讲)。在这个程序里,我们已经在前面输出了132字节,所以这里的$就是132。因此nask先用0x1fe减去132,得出378这一结果,然后连续输出378个字节的0x00。

那这里我们为什么不直接写378,而非要用$呢?这是因为如果将显示信息从“hello, world”变成“this is a pen.”的话,中间要输出0x00的字节数也会随之变化。换句话说,我们必须保证软盘的第510字节(即第0x1fe字节)开始的地方是55 AA。如果在程序里使用美元符号($)的话,汇编语言会自动计算需要输出多少个00,我们也就可以很轻松地改写输出信息了。

■■■■■

既然可以毫不费力地改写显示的信息,就一定要好好发挥这一功能,让我们的操作系统显示出自己喜欢的一句话,让它成为一个只属于我们自己的、世界上独一无二的操作系统。不过遗憾的是现在它还不能显示汉字。当然大家也可以尝试一下,但由于这个程序还没有显示汉字的功能,所以显示出来的都是乱码,因此大家先将就一下,用英语或拼音吧。

■■■■■

最后再给大家解释一下程序中出现的几个专门术语。时间不早了,我们今天就到这吧。其他的留待明天再说。

TAB=4….......有的文本编辑器可以调整TAB键的宽度。请使用这种编辑器的人将TAB键的宽度设定成4,这样源程序更容易读。可能有人说,我这里只能用记事本(notepad), TAB键宽度固定为8,想调都没法调。没关系,明天笔者来推荐一个好用的文本编辑器。

FAT12格式...(FAT12 Format)用Windows或MS-DOS格式化出来的软盘就是这种格式。我们的helloos也采用了这种格式,其中容纳了我们开发的操作系统。这个格式兼容性好,在Windows上也能用,而且剩余的磁盘空间还可以用来保存自己喜欢的文件。

启动区..........(boot sector)软盘第一个的扇区称为启动区。那么什么是扇区呢?计算机读写软盘的时候,并不是一个字节一个字节地读写的,而是以512字节为一个单位进行读写。因此,软盘的512字节就称为一个扇区。一张软盘的空间共有1440KB,也就是1474560字节,除以512得2880,这也就是说一张软盘共有2880个扇区。那为什么第一个扇区称为启动区呢?那是因为计算机首先从最初一个扇区开始读软盘,然后去检查这个扇区最后2个字节的内容。如果这最后2个字节不是0x55 AA,计算机会认为这张盘上没有所需的启动程序,就会报一个不能启动的错误。(也许有人会问为什么一定是0x55 AA呢?那是当初的设计者随便定的,笔者也没法解释)。如果计算机确认了第一个扇区的最后两个字节正好是0x55 AA,那它就认为这个扇区的开头是启动程序,并开始执行这个程序。

IPL.........…....initial program loader的缩写。启动程序加载器。启动区只有区区512字节,实际的操作系统不像hello-os这么小,根本装不进去。所以几乎所有的操作系统,都是把加载操作系统本身的程序放在启动区里的。有鉴于此,有时也将启动区称为IPL。但hello-os没有加载程序的功能,所以HELLOIPL这个名字不太顺理成章。如果有人正义感特别强,觉得“这是撒谎造假,万万不能容忍!”,那也可以改成其他的名字。但是必须起一个8字节的名字,如果名字长度不到8字节的话,需要在最后补上空格。

启动..........….(boot)boot这个词本是长靴(boots)的单数形式。它与计算机的启动有什么关系呢?一般应该将启动称为start的。实际上,boot这个词是bootstrap的缩写,原指靴子上附带的便于拿取的靴带。但自从有了《吹牛大王历险记》(德国)这个故事以后,bootstrap这个词就有了“自力更生完成任务”这种意思(大家如果对详情感兴趣,可以在Google上查找,也可以在帮助和支持网页http://hrb.osask.jp上提问)。而且,磁盘上明明装有操作系统,还要说读入操作系统的程序(即IPL)也放在磁盘里,这就像打开宝物箱的钥匙就在宝物箱里一样,是一种矛盾的说法。这种矛盾的操作系统自动启动机制,被称为bootstrap方式。boot这个说法就来源于此。如果是笔者来命名的话,肯定不会用bootstrap这么奇怪的名字,笔者大概会叫它“多级火箭式”吧。