Day01

今天用二进制,以及不像汇编的汇编写代码。。

二进制文件

helloos0

本质上所有文件都是二进制文件。。所以我们也可以直接用二进制编辑器来写一个光盘映像。但是写起来就完全不知道自己是在写什么(毕竟没有什么翻译)。
另外,还有一些简单的批处理程序,帮助我们很方便的进行一些cmd操作。

文本编辑器示例
bin

不那么像汇编的汇编

helloos1

到这步时候还是有点像二进制编辑,初学就先把代码都放上来吧。

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

稍微有点汇编的感觉

helloos2

认认真真地抄了一遍(其实有好多遍纠错),不懂的先放这里,以后慢慢了解。
部分汇编助记符的用法已经放到这里了。

; hello-os
; TAB=4

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

    ; define byte : 一字节
    DB 0xeb, 0x4e, 0x90
    ; 该汇编语言下DB可以直接写字符串
    DB "HELLOIPL" ; 启动区的名称可以是任意的字符串(8字节)
    ; define word : 2字节
    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)
    ; define double word : 4字节
    DD 0 ; 不使用分区(必须是0)
    DD 2880 ; 重写一次磁盘的大小
    DB 0, 0, 0x29 ; 意义不明,固定
    DD 0xffffffff ; (可能是)卷标号码
    DB "HELLO-OS   " ; 磁盘的名称(11字节)
    DB "FAT12   " ; 磁盘格式名称(8字节)
    ; reserve byte 空出一定数量字节
    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

一些感想

不得不说,抄代码真的很严格,稍微写错一个数字,就会导致loading error。。