30天开发操作系统 第 1 天
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
从计算机结构到汇编语言入门
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
一、二进制编译器
我们直接上手,不用C,也不用汇编,而是采用一个很奇特的工具来进行开发。
大家是不是懵圈了哦,怎么搞的,和之前说的完全不一样嘛!没事,这就和刚开始学C的时候的include 一样,先照着写上,过些日子就会知道它的道理啦!
下载顶部的bz1621,然后运行exe文件,之后进行输入EB4E904845… 这样写着写着右面是不是就出现字母了呢?.N.HELLOIPL…大家是不是有点明白了呢?
从000090之后全都是0,一直输入到16800这个地址(大家可以复制),在0001F0和001400附近不完全是00。然后检查一下,是不是都写对哦。保存成helloos.img(你也可以保存成你喜欢的名字)
二、使用步骤
1.如何运行?
然后怎么办呢? 我们把输入的内容保存下来就完成了软盘映像文件的制作。
下载tolset的文件夹,把这个文件夹放到硬盘任何一个位置,不需要修改注册表也不同设置路径。我们以后的开发都需要这个文件夹。
接下来打开刚才下载的tolset文件夹,在这个文件夹里面新建一个文件夹 – helloos0,并把前面咱们写的helloos.img复制进来。在当前的tolset文件夹下有z_new_w的子文件夹,把cons_nt.bat 这个文件也复制到helloos文件夹中。
然后在文件夹helloos0里单击鼠标右键,新建一个文本文件,并将其命名为 run.bat 然后出现对话框的话,选择“是”。创建后在这个文件上右击选择“编辑”,输入下面内容并保存下来哦。
copy helloos.img …\z_tools\qemu\fdimage0.bin
…\z_tools\make.exe -C …\z_tools\qemu
然后按照同样的步骤创建install.bat 写入以下内容
…\z_tools\imgtol.com w a: helloos.img

已经让这些二进制数字运转起来了,真了不起!但是大家还是比较疑惑吧,这些“EB 4E 90 48 45 …” 到底是什么意思。剩下的时间,我们会慢慢讲解这个问题。大家放心,这只让大家先看到操作系统的样子,之后就会回到C语言开发啦!
2.汇编程序初体验
现在我们就来写一个汇编语言,用它来生成一个跟刚才完全一样的helloos.img吧。我们这次用的汇编语言编译器是这本书作者的,叫做:nask – 模仿 NASK。
代码如下:
DB 0xeb, 0x4e, 0x90, 0x48, 0x45, 0x4c, 0x4c, 0x4f
DB 0x49, 0x50, 0x4c, 0x00, 0x02, 0x01, 0x01, 0x00
DB 0x02, 0xe0, 0x00, 0x40, 0x0b, 0xf0, 0x09, 0x00
DB 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
DB 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x29, 0xff
DB 0xff, 0xff, 0xff, 0x48, 0x45, 0x4c, 0x4c, 0x4f
DB 0x2d, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x46, 0x41
DB 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00
RESB 16
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, 0x0a, 0x0a, 0x68, 0x65
DB 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72
DB 0x6c, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 368
DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 4600
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 1469432
仔细看一下就能发现这个文件内容与我们用二进制编译器输入的内容是一样的。
将其命名为 :helloos.img。接着我们打开 !cons_nt.bat 在里面输入:
…\z_tools\nask.exe helloos.nas helloos.img
这样我们就得到了映像文件helloos.img。
每次汇编的时候,我们都要输入刚才那一串指令,是不是很麻烦哦。我们做了一个批处理文件 asm.bat 。有了这个文件,我们在 !con 打开的命令行窗口里输入 “asm",就可以生成helloos.img。在用 “asm” 制作成 img 文件后,在执行 “run” 命令,就和之前的结果是一样的哦!
“哎,上面的是啥意思嘛,你还没说呢”
大肯定是想知道DB 和 RESB 吧,哈哈。 这就是汇编里面的关键字
DB – data byte – 往文件里是直接写入一个字节的指令
RESB – reserve byte – 从现在开始的地址空出1个字节,
在 nask 里,自动填 0 了
汇编语言中db 和 DB 一样
大家应该知道 0x是16进制数吧 … 0x0000 0000 两个16进制就是一个字节 ,一个字节 – char 占 8 个 bit。
加工润色
我们已经把程序变成了22行,这让我们很高兴。不过,大家应该都觉得很难过,这并不能让我们知道这段程序是干什么的。所以我们就改写一下,让别人也能看懂。
; 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
“ ;”是注释命令 还有DB – 怎么写上了 “hello,world”了?
对哦,我们可以直接用它写字符串。大家是不是很惊讶,一个字符占8个字节,就这样向下排列。0x0a 是 end-of-line characters.
(To define string of characters, enclose them in single or double quotation marks. The most common type of string ends with a null byte.)
ex:
greeting DB “Good night”,0
这是汇编语言里的描述,大家可能想知道怎么才能一个一个的拿到他们呢… 别急嘛,过几天就知道喽
还有个就是 :“$” 这是咋回事,咋还出来美元了! 它的意思就是当前地址,就是要一直填写 0 到 0x001fe 这个地方。
(The $ is called location counter.For example, the following declaration declares a variable named slefPtr and initializes it with the variable’s offset value:
selfPtr DWORD $
)
这些英文都是从书中抄来的,应该不难理解吧,我也不知道咋翻译比较好,就直接抄上来啵。
总结
提示:这里对文章进行总结:
今天就到这里吧! 大家记得自己去查查程序中的术语 – TAB = 4 ,FAT12格式,启动区,IPL,启动(boot)
有疑问大家留言讨论哦,今天的代码及工具都在文章开头的下载中啦!