30天自制操作系统 下载本文

2 究竟做了些什么 …… 21

保存成文件。所以它就是我们的秘密武器,也就是说只要有了二进制编辑器,随便什么文件我们 都能做出来。(厉害吧!)如果大家在商店里看到一个软件,很想要而又不想花那么多钱的话,那 就干脆就回家用二进制编辑器自己做一个算啦!用这个方法我们完全可以自己制作出一个与店里 商品一模一样的东西来。看上一个500万像素的数码相机,但是太贵了买不起?那有什么关系? 我们只要有二进制编辑器在手,就可以制作出毫不逊色于相机拍摄效果的图像,而且想做几张就 可以做几张。要是C编译器太贵了买不起,也不用郁闷。即使没有C编译器,我们也可以用二进 制编辑器做出一个与编译器生成文件完全一样的执行文件,而且就连C编译器本身都可以用二进 制编辑器做出来。

1 1 3 20

有了这么强大的工具,制作操作系统就是小菜一碟。道理就是这么简单,所以我们这次不费 吹灰之力就做了个操作系统出来也是理所当然的。或许有人会想―就为了讲这么个小事,有必要 长篇大论写这么多吗?‖其实不然,如果我们对CPU的基础有了彻底的理解,以后的内容就好懂 多了。

21 22

■■■■■

7 8 9 10 11 12 13 14 15 16

―喂,且慢,我明白了二进制编辑器就是编辑二进制数的软件,可是在你让我输入你的 helloos.img的时候,除了0和1以外,不是还让我输入了很多别的东西吗?你看,第一个不就是E 吗?这哪里是什么二进制数?分明是个英文字母嘛!‖……噢,不好意思,这说得一点错都没有。 虽然二进制数与电信号有很好的一一对应关系,但它有一个缺点,那就是位数实在太多了, 举个例子来说,如果我们把1234写成二进制数,就成了10011010010,居然长达11位。而写成十 进制数,只用4位就够了。因为这样也太浪费纸张了,所以计算机业界普遍使用十六进制数。十 进制数的1234写成十六进制数,就是4D2,只用3位就够了。

那为什么非要用十六进制数呢,用十进制数不是也挺好的吗?实际上,我们可以非常简便地 把二进制数写成十六进制数。

二进制数和十六进制数对照表

0000 – 0 0001 – 1 0010 – 2 0011 – 3

0100 – 4 0101 – 5 0110 – 6 0111 – 7

1000 – 8 1001 – 9 1010 – A 1011 – B

1100 – C 1101 – D 1110 – E 1111 – F

有了这个对照表,我们就能轻松进行二进制与十六进制之间的转换了。将二进制转换为十六 进制时,只要从二进制数的最后一位开始,4位4位地替换过来就行了。如:

100 1101 0010 → 4D2

反之,把十六进制数的4D2转换为二进制数的100 1101 0010也很简单,只要用上面的对照表 反过来变换一下就行了。而十进制数变换起来就没这么简单了。同理,八进制数是把3位一组的

22 …… 第 1 天:从计算机结构到汇编程序入门

二进制数作为一个八进制位来变换的,这种计数法在计算机业界也偶有使用。

因此我们在输入EB的时候,实际上是在输入11101011,所以它其实是个十六进制编辑器,但 笔者习惯称它为二进制编辑器,希望大家不要见怪。

■■■■■

虽然笔者对二进制编辑器如此地赞不绝口,但用它也解决不了什么实际问题。因为这就相当 于―只要有了笔和纸,什么优秀的小说都能写出来‖一样。笔和纸不过就是笔和纸而已,实际上 对创作优秀的小说也帮不上多大的忙。所以大家在写程序时,用的都是文本编辑器和编译器,没 有谁只用二进制编辑器来做程序的。大家照相用的也都是数码照相机,没有谁只用二进制编辑器 来做图像文件。因此,我们用二进制编辑器进行的开发就到此为止,接下来我们要调转方向,开 始用编程语言来继续我们的开发工作。不过有了这次的经验,我们就知道了如果今后遇到什么特 殊情况还可以使用二进制编辑器,它是非常有用的。而且后面章节中我们偶尔也会用到它。

33

初次体验汇编程序

好,现在就让我们马上来写一个汇编程序,用它来生成一个跟刚才完全一样的helloos.img吧。 我们这次使用的汇编语言编译器是笔者自己开发的,名为―nask‖,其中的很多语法都模仿了自 由软件里享有盛名的汇编器―NASM‖,不过在―NASM‖的基础之上又提高了自动优化能力。 超长的源代码

DB 0xeb, 0x4e, 0x90, 0x48, 0x45, 0x4c, DB 0x49, 0x50, 0x4c, 0x00, 0x02, 0x01, DB 0x02, 0xe0, 0x00, 0x40, 0x0b, 0xf0, DB 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, DB 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, (为节省纸张,这里省略中间的18万4314行) DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x4c, 0x01, 0x09, 0x00, 0x29,

0x4f 0x00 0x00 0x00 0xff

0x00, 0x00

我们使用复制粘帖的方法,就可以写出这样一个超长的源代码来,将其命名为―helloos.nas‖, 并保存在helloos0中。仔细看一下就能发现这个文件内容与我们用二进制编辑器输入的内容是一 模一样的。

接着,我们用―!cons_nt.bat‖或是―!cons_9x.bat‖(我们在前面已经说过,要根据Windows

的版本决定用哪一个。以后每次都这样解释一遍的话比较麻烦,所以我们就将它简写为!cons好了) 打开一个命令行窗口(console),输入以下指令(提示符部分不用输入):

提示符①>..\\¥z_tools¥nask.exe helloos.nas helloos.img ——————————

① prompt,出现在命令行窗口中,提示用户进行输入的信息。

3 初次体验汇编程序 …… 23

这样我们就得到了映像文件helloos.img。

好,我们的第一个汇编语言程序就这样做成了!……不过这么写程序也太麻烦了,要做个18 万行的程序,不但浪费时间,还浪费硬盘空间。与其这样还不如用二进制编辑器呢,不用输入―0x‖、 ―,‖什么的,还能轻松一点。

1 1 3 20 21

■■■■■

其实要解决这个问题并不难,如果我们不只使用DB指令,而把RESB指令也用上的话,就可 以一下将helloos.nas缩短了,而且还能保证输出的内容不变,具体我们来看下面。 正常长度的源程序

DB 0xeb, 0x4e, DB 0x49, 0x50, DB 0x02, 0xe0, DB 0x12, 0x00, DB 0x40, 0x0b, DB 0xff, 0xff, DB 0x2d, 0x4f, DB 0x54, 0x31, RESB16

DB 0xb8, 0x00, DB 0x8e, 0xd8, DB 0x04, 0x83, DB 0xb4, 0x0e, DB 0xee, 0xf4, DB 0x6c, 0x6c, DB 0x6c, 0x64, RESB368

DB 0x00, 0x00, DB 0xf0, 0xff, RESB4600

DB 0xf0, 0xff, RESB1469432

0x90, 0x4c, 0x00, 0x02, 0x00, 0xff, 0x53, 0x32,

0x48, 0x00, 0x40, 0x00, 0x00, 0x48, 0x20, 0x20,

0x45, 0x02, 0x0b, 0x00, 0x00, 0x45, 0x20, 0x20,

0x4c, 0x01, 0xf0, 0x00, 0x00, 0x4c, 0x20, 0x20,

0x4c, 0x01, 0x09, 0x00, 0x29, 0x4c, 0x46, 0x00,

0x4f 0x00 0x00 0x00 0xff 0x4f 0x41 0x00

22 7 8 9 10 11 12 13 14

0x00, 0x8e, 0xc6, 0xbb, 0xeb, 0x6f, 0x0a, 0x8e, 0xc0, 0x01, 0x0f, 0xfd, 0x2c, 0x00, 0xd0, 0xbe, 0x3c, 0x00, 0x0a, 0x20, 0x00, 0xbc, 0x74, 0x00, 0xcd, 0x0a, 0x77, 0x00, 0x00, 0x7c, 0x74, 0x10, 0x68, 0x6f, 0x00, 0x7c 0x8a 0x09 0xeb 0x65 0x72 0x00

0x00, 0x00, 0x00, 0x00, 0x55, 0xaa 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 0xff, 0x00, 0x00, 0x00, 0x00, 0x00

我们自己动手输入这段源程序比较麻烦,所以笔者把它放在附带光盘的projects\\01_day\\ helloos1目录下了。大家只要把helloos1文件夹复制粘帖到tolset文件夹里就可以了。之前的helloos0 文件夹以后就不用了,我们可以把它删除,也可以放在那里留作纪念。顺便说一下,笔者将helloos0 文件夹名改为了helloos1,删掉了其中没用的文件,新建并编辑了需要用到的文件,这样就做出 了新的helloos1文件夹。操作系统就是这样一点一点地成长起来的。

每次进行汇编编译的时候,我们都要输入刚才的指令,这太麻烦了,所以笔者就做了一个批 处理文件①asm.bat。有了这个批处理文件,我们只要在用―!cons‖打开的命令行窗口里输入―asm‖,

15

——————————

① batch file,基本上只是将命令行窗口里输入的命令写入文本文件。虽然还有功能更强的处理,但本书中我们用不 到。所谓批处理就是批量处理,即一次处理一连串的命令。

16

24 …… 第 1 天:从计算机结构到汇编程序入门

就可以生成helloos.img文件。在用―asm‖作成img文件后,再执行―run‖指令,就可以得到与 刚才一样的结果。

■■■■■

DB指令是―data byte‖的缩写,也就是往文件里直接写入1个字节的指令。笔者喜欢用大写 字母来写汇编指令,但小写的―db‖也是一样的。

在汇编语言的世界里,这个指令是程序员的杀手锏,也就是说只要有了DB指令,我们就可 以用它做出任何数据(甚至是程序)。所以可以说,没有用汇编语言做不出来的文件。文本文件 也好,图像文件也好,只要能叫上名的文件,我们都能用汇编语言写出来。而其他的语言(比如 C语言)就没有这么万能。

RESB指令是―reserve byte‖的略写,如果想要从现在的地址开始空出10个字节来,就可以

写成RESB 10,意思是我们预约了这10个字节(大家可以想象成在对号入座的火车里,预订了10 个连号座位的情形)。而且nask不仅仅是把指定的地址空出来,它还会在空出来的地址上自动填 入0x00,所以我们这次用这个指令就可以输出很多的0x00,省得我们自己去写18万行程序了,真 是帮了个大忙。

这里还要说一下,数字的前面加上0x,就成了十六进制数,不加0x,就是十进制数。这一点 跟C语言是一样的。

44

加工润色

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

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

; hello-os ; TAB=4

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

DB DB DW DB

0xeb, 0x4e, 0x90

\启动区的名称可以是任意的字符串(8字节) 512; 每个扇区(sector)的大小(必须为512字节) 1; 簇(cluster)的大小(必须为1个扇区)