《30天自制操作系统》1.初体验汇编程序

我们这次使用的汇编语言编译器是原书作者自己开发的,名为“nask”,很多语法和著名的汇编语言编译器nasm很像。由于原书作者没有给出有哪些不同,这里就无法给出不同了!
现在仅仅使用汇编语言中的DB指令来写个“操作系统”吧。
DB指令是"define byte"的缩写,往文件里写入1个字节
 
超长的源代码
 
1      DB     0xeb, 0x4e, 0x90, 0x48, 0x45, 0x4c, 0x4c, 0x4f
2      DB     0x49, 0x50, 0x4c, 0x00, 0x02, 0x01, 0x01, 0x00
3      DB     0x02, 0xe0, 0x00, 0x40, 0x0b, 0xf0, 0x09, 0x00
4      DB     0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
5      DB     0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x29, 0xff
6 
7           这里省略中间的18万4314行
8 
9      DB     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
View Code

 

保存为helloos.nas,执行下面的命令编译成helloos.img
..\z_tools\nask.exe helloos.nas helloos.img(红线部分是我输入的)
 
 
 
然后把helloos.img放到作者光盘中的qemu中运行吧!
 
 
鉴于上面的代码是在是太长,简直令人发指!稍微修改下,缩短其中的代码长度。再使用一个新的指令RESB
RESB指令是"reserve byte"的略写,用0x00填充字节。如果想要在接下来的地址里填充10个0x00,可以写成RESB 10
 
正常长度的源程序
 
 1      DB     0xeb, 0x4e, 0x90, 0x48, 0x45, 0x4c, 0x4c, 0x4f
 2      DB     0x49, 0x50, 0x4c, 0x00, 0x02, 0x01, 0x01, 0x00
 3      DB     0x02, 0xe0, 0x00, 0x40, 0x0b, 0xf0, 0x09, 0x00
 4      DB     0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
 5      DB     0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x29, 0xff
 6      DB     0xff, 0xff, 0xff, 0x48, 0x45, 0x4c, 0x4c, 0x4f
 7      DB     0x2d, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x46, 0x41
 8      DB     0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00
 9      RESB     16
10      DB     0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
11      DB     0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
12      DB     0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
13      DB     0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb
14      DB     0xee, 0xf4, 0xeb, 0xfd, 0x0a, 0x0a, 0x68, 0x65
15      DB     0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72
16      DB     0x6c, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00
17      RESB     368
18      DB     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
19      DB     0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
20      RESB     4600
21      DB     0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
22      RESB     1469432
View Code

 

 
保存为helloos1.nas,执行下面的命令编译成helloos1.img
..\z_tools\nask.exe helloos1.nas helloos1.img
然后把helloos1.img放到作者光盘中的qemu中运行吧!
运行结果和上面是一样的,就不截图了!
 
 
那个正常长度的源程序虽然变短了,但是还是反人类的,简直无法阅读,下面来加工润色下
 
有模有样的源代码
 
;hello-os

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

          DB          0xeb, 0x4e, 0x90
          DB          "HELLOIPL"          ; 启动区的名称,8字节大小
          DW          512                    ; 每个扇区大小,必须为512字节
          DB          1                    ; 簇(cluster)的大小,必须为1扇区
          DW          1                    ; FAT的起始位置(一般从第1个扇区开始)
          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
View Code

 

 
上面的源代码中,;是注释的意思,如果nask看到“;”字符后面的文字不会解析的,供程序员查阅
DW指令是"default word"的缩写,每一次可以写入一个word(2字节)长的内容,因为在计算机汇编的语言世界里,word指的是16位的意思,也就是2字节
DW指令是"default double-word"的缩写,每一次可以写入一个双word(4字节)长的内容
RESB 0x1fe-$,$是一个全局变量,保存了上面的代码已经填充了多少个字节 。为了保证执行到这一行代码,一级有0x1fe个字节填充了相应的数据。
为什么是0x1fe呢?因为计算机首先从第一个扇区(512字节=0x200)开始读取数据,如果该扇区最后两个字节为0x55 0xAA ,则认为该扇区有启动程序。你会看到后面紧接着DB 0x55 ,0xaa.
正好0x1fe + 2 = 0x200 = 512字节
 
运行结果就不贴截图了
 
注:本文的大部分内容来自《30天自制操作系统这本书》,只是将一些内容和自己理解的部分记录下来,难免会出现错误,君请谅解!
posted @ 2014-09-09 21:14  艾斯泽  阅读(2021)  评论(0编辑  收藏  举报