guangzhou



shanghai

Recent posts:
Blog index
About
RSS

自制OS(1) 从计算机结构到汇编程序入门

May 10, 2016     C   889   

首先下载一个“二进制编辑器”(Binary Editor),是一种能直接对二进制数进行编辑的软件

下载地址:http://download.csdn.net/download/missxin/8500489

双击启动Bz.exe程序打开BZ软件,从键盘上直接输入EB4E904845……就可以了,从菜单上选择“文件”(File)→“另存为”(Save As),画面上就会弹出保存文件的对话框。我们可以随便取个名字进行保存,使用“helloos.img”。当想要打开保存过的文件时,首先要启动Bz.exe,从菜单上选择“文件”(File)→“打开”(Open),然后选择目标文件,这样原来保存的内容就能显示出来了。可是这个时候不管我们怎么努力按键盘,它都一点反应也没有。这是怎么回事?其实只要从菜单里选择“编辑”(Edit)→“只读”(Read Only)就可以进入编辑状态了。

我们把输入的内容保存下来就完成了软盘映像文件的制作,这时查看一下文件属性,应该能看到文件大小正好是1474560字节(=1440×1024字节)。然后我们将这个文件写入软盘(具体后述),并用它来启动电脑。画面上会显示出“hello, world”这个字符串。目前的程序虽然简单,但毕竟一打开电脑它就能够自动启动,还能在屏幕上显示出一句话来

由于helloos.img中的代码太长,而且其中的0非常多,所以使用DB指令和RESB指令将其代码加以简化,但效果等价:

	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

DB命令(data byte):往文件里写入一个字节

RESB(reserve byte):从现在的地址开始空出指定字节的位置出来

上面的代码不够清晰易懂,将其改写成下面的等效的代码,并加上注释:

; 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指令的新用法,直接使用它写字符串,汇编语言会将其直接将每个字符转换为相应的字节

DW(data word)两个字节,DD(data double-word)四个字节

RESB 0x1fe-$其中“$”表示这一行目前的字节数,程序前面已经输出了132字节,所以$=132,0x1fe-132=378,所以后面连续输出378字节的0x00,必须保证软盘的第510字节(即第0x1fe字节)开始的地方是55 AA,这样做的原因是为了保证程序的可扩展,因为打印的信息可能不是“hello world”


最后解释一下相关的几个术语

TAB=4…………这样做的原因是使程序看起来更加的清晰

FAT12格式…………用windows或DOS格式化出来的软盘就是这种格式,便于在windows上面使用,兼容性好

启动区…………软盘第一个扇区称为启动区。扇区:计算机读写软盘的时候以512字节为单位进行。软盘的512字节就称为一个扇区,一张软盘的空间供1440KB,即是1474560字节,一共2880个扇区。计算机首先从最初的一个扇区开始读软盘,然后检查这个扇区最后的2个字节的内容,如果这最后2个字节不是55 AA,计算机就会认为这张盘上没有所需的启动程序,就会报一个不能启动的错误。

IPL…………inital program loader。启动程序加载器。几乎所有的OS都是把加载OS本身的程序放在启动区里的

如果文章对您有帮助,欢迎点击下方按钮打赏作者

Comments

No comments yet.
To verify that you are human, please fill in "七"(required)