【操作系统学习实践】从零开始制作,开发操作系统(一)—— 汇编语言的编写以及映像文件的制作

本文作者bay_Tong桐小白分享了从零开始制作操作系统的初步步骤,涉及汇编语言编写、FAT12格式软盘启动区代码、QEMU虚拟器的使用。通过编写简单的汇编程序并在QEMU中运行,展示了操作系统开发的基础过程。
摘要由CSDN通过智能技术生成

halo~我是bay_Tong桐小白
本文内容是桐小白个人对所学知识进行的总结和分享,知识点会不定期进行编辑更新和完善,了解最近更新内容可参看更新日志,欢迎各位大神留言、指点


身体、心理等各种原因,停滞住了两个月,没有学习,没有写文章,为了恢复状态每天都在睡觉休息,揽了一些小型比赛调整自己“强迫”自己学习,目前仍然有些低烧,还在慢慢调整,努力开始往起捡专业课以及考研复习,更新文章较慢,给关注我的新老朋友道声抱歉~

【本学习实践内容以《30天自制操作系统》[作者 川合秀实;译者 周自恒、李黎明、曾祥江、张文旭] 一书为主要参考资料,辅以其它操作系统相关书籍与相关知识进行探索、实践、创新、学习,欢迎各位大神留言、指点】

从零开始制作,开发操作系统(一)—— 汇编语言的编写以及映像文件的制作

【更新日志】

最近更新:

  • 暂无编辑记录,持续更新中……

从这里开始就要着手编写操作系统啦,我们知道计算机能直接识别的只有0/1码这样的二进制机器语言,而为了方便记忆和识别用助记符来标识指定的0/1序列,出现了汇编语言。操作系统的开发离不开汇编语言,这里桐小白就直接用汇编语言开始编写啦,当然刚开始的文件很简单,也可以直接用二进制/十六进制来写,桐小白将两种文件的编写以及相关内容都进行总结啦,而对于计算机语言的相关内容桐小白在之前的文章里有写到过,就暂时不在这里做过多解释啦,相关内容详细可以见桐小白专业基础专栏文章《计算机语言处理相关知识要点区分汇总》

平台/工具

QEMU虚拟器: 由于操作环境的限制,这里使用QEMU虚拟器进行实验实践。

QEMU是一套由法布里斯·贝拉所编写的以GPL许可证分发源码的模拟处理器,在GNU/Linux平台上使用广泛
QEMU有两种主要运作模式:用户模式(User mode模拟模式)和系统模式(System mode模拟模式)

  • User mode模拟模式能启动那些为不同中央处理器编译的Linux程序
  • System mode模拟模式能模拟整个电脑系统,包括中央处理器及其他周边设备。它使得为跨平台编写的程序进行测试及除错工作变得容易。其亦能用来在一部主机上虚拟数部不同虚拟电脑

文本编辑器: 虽然Windows下的记事本、Linux下的gedit等都很方便,但是这里桐小白还是推荐使用notepad++来进行汇编代码编写

文本编辑器是用作编写普通文字的应用软件,常用来编写程序的源代码。Windows下的记事本,Mac OS X下的文本编辑,Linux下的vi、gedit等均是常见的文本编辑器

二进制编辑器: 主要用来进行二进制代码的编写和查看,常见的是Bz1621.lzh这款二进制编辑器,这里桐小白推荐010 editor这款软件,它的功能更加丰富强大

汇编语言编写

【这里桐小白就直接用汇编语言进行程序的编写啦,会对程序逻辑进行必要的总结,对用到的重要指令进行归纳和说明,但是对于汇编语言的语法、指令、机器码等具体知识桐小白就不在这里赘述啦,详细可以见桐小白微机原理与接口技术专栏的文章以及计算机组成原理专栏的《指令系统总结——基本知识要点汇总》文章、《中央处理器总结——基本知识要点汇总》的微程序控制器部分】

下面就直接开始动手进行编写啦,桐小白在之前有简单学习过汇编语言相关知识,程序比较简单也写明了注释,暂时就不过多解释代码含义啦

PS:对于操作系统的开发,启动区的程序和磁盘映像文件往往是分开制作的,由于刚刚起步,编写的映像文件较小,暂时就合成一个文件来写啦

初步编写

; hello-os
; TAB=4

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

		DB		0xeb, 0x4e, 0x90
		DB		"HELLOIPL"		; 启动区的名称可以是任意的字符串(8字节)
		DW		512				; 每个扇区的大小(必须为512字节)
		DB		1				; 簇的大小(必须为1个扇区)
		DW		1				; FAT的起始位置(一般从第一个扇区开始)
		DB		2				; FAT的个数(必须为2)
		DW		224				; 根目录的大小(一般设成224项)
		DW		2880			; 该磁盘的大小(必须是2880扇区)
		DB		0xf0			; 磁盘的种类(必须是0xf0)
		DW		9				; FAT的长度(必须是9扇区)
		DW		18				; 1个磁道有几个扇区
		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——data byte的缩写,即往文件里直接写入1个字节(8位数据)的指令

DW——data word的缩写,即往文件里直接写入2个字节(16位数据)的指令,高8位数据字节存入高地址字节中,而低8位数据字节则存入低地址字节中

RESB——reserve byte的缩写,用于预留出一部分空间(空出来的地址上会自动填0x00),如 从现在的地址开始空出十个字节,语句为RESB 10

$ 是预定义符号,等价于当前正汇编到的段的当前偏移值,如

  • jmp $+3 表示要向前跳转到距离这条指令3个字节的地方
  • jmp $-3 表示要向后跳转到距离这条指令3个字节的地方
  • RESB 0x1fe-$ 表示从当前直到0x001fe地址单元见的空间均预留出来,即填入0x001fe

其它说明

TAB=4——制表键[TAB]的宽度

FAT12格式——DOS时代就开始使用的文件系统(File System),直到2009年仍然在软盘上使用

IPL——initial program loader的缩写,即启动程序加载器。由于启动区MBR只有512字节,往往是存放不下整个操作系统的,因此启动区存放的代码程序的主要作用是告诉计算机到硬盘的哪一个位置去找操作系统。这个用于加载操作系统的加载程序就是启动程序加载器,有时也直接将启动区称为IPL

进一步改写

; hello-os
; TAB=4

		ORG		0x7c00			; 指明程序的装载地址

; 以下的记述用于标准FAT12格式的软盘

		JMP		entry
		DB		0x90
		DB		"HELLOIPL"		; 启动区的名称可以是任意的字符串(8字节)
		DW		512				; 每个扇区的大小(必须为512字节)
		DB		1				; 簇的大小(必须为1个扇区)
		DW		1				; FAT的起始位置(一般从第一个扇区开始)
		DB		2				; FAT的个数(必须为2)
		DW		224				; 根目录的大小(一般设成224项)
		DW		2880			; 该磁盘的大小(必须是2880扇区)
		DB		0xf0			; 磁盘的种类(必须是0xf0)
		DW		9				; FAT的长度(必须是9扇区)
		DW		18				; 1个磁道有几个扇区
		DW		2				; 磁头数(必须是2)
		DD		0				; 不使用分区,必须是0
		DD		2880			; 重写一次磁盘大小
		DB		0,0,0x29		; 意义不明,固定
		DD		0xffffffff		; (可能是)卷标号码
		DB		"HELLO-OS   "	; 磁盘的名称(11字节)
		DB		"FAT12   "		; 磁盘格式名称(8字节)
		RESB	18				; 先空出18字节

; 程序核心

entry:
		MOV		AX,0			; 初始化寄存器
		MOV		SS,AX
		MOV		SP,0x7c00
		MOV		DS,AX
		MOV		ES,AX

		MOV		SI,msg
putloop:
		MOV		AL,[SI]
		ADD		SI,1			; 给SI加1
		CMP		AL,0
		JE		fin
		MOV		AH,0x0e			; 显示一个文字
		MOV		BX,15			; 指定字符颜色
		INT		0x10			; 调用显卡BIOS
		JMP		putloop
fin:
		HLT						; 让CPU停止,等待指令
		JMP		fin				; 无限循环

msg:
		DB		0x0a, 0x0a		; 换行2次
		DB		"hello, world"
		DB		0x0a			; 换行
		DB		0

		RESB	0x7dfe-$		; 填写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

汇编指令说明

entry、putloop、fin、msg——均是用于指定汇编程序的入口点,是一个标签的声明

ORG——定义程序或数据块的起始地址

JMP——无条件跳转指令,可转到内存中任何程序段。转移地址可在指令中给出,也可以在寄存器中给出,或在储存器中指出

MOV——数据传送指令,也是最基本的编程指令,用于将一个数据从源地址传送(复制)到目标地址

ADD——加法指令

CMP——比较指令,对操作数之间运算比较,根据结果设置相关的条件标志位(SF、ZF、CF、OF)

JE——条件跳转指令,如果ZF标志位为0则跳转到指定的地址

INT——软件中断指令,可以调用不同的函数

HLT——处理器暂停指令,使程序停止运行,处理器进入暂停状态,不执行任何操作,不影响标志

对应二进制文件

在这里插入图片描述

QEMU虚拟器运行

把汇编语言写的程序写好之后,它就是一个及其简单的操作系统的源代码文件啦,起个名字吧,就叫helloos.nas,保存在指定文件夹下

下一步就把它进行汇编生成机器码映像文件,装载进虚拟器里查看效果吧(当然如果直接进行的二进制文件编写,不需要汇编就可以直接装载到虚拟器里运行啦)

这里参考书作者给出了他自己开发的汇编程序nas.exe,以及QEMU虚拟器的相关批处理文件,所以就直接用它来进行映像文件的生成和虚拟器的启动吧

!cons_nt.bat文件

  • 代码内容:cmd.exe
  • 作用:启动cmd命令窗口

asm.bat文件

  • 代码内容:…\z_tools\nask.exe helloos.nas helloos.img
  • 作用:运行笔者提供的汇编程序文件,将helloos.nas汇编成二进制文件helloos.img

install.bat文件

  • 代码内容:…\z_tools\imgtol.com w a: helloos.img
  • 作用:向QEMU虚拟器装载helloos.img文件

run.bat文件

  • 代码内容:
    copy helloos.img …\z_tools\qemu\fdimage0.bin
    …\z_tools\make.exe -C …/z_tools/qemu
  • 作用:启动QEMU虚拟器

运行!cons_nt.bat文件,输入asm并执行,即完成映像文件的生成;输入run,则完成映像文件的装载以及QEMU的启动,如下图所示

在这里插入图片描述
可以看到QEMU虚拟器启动并完成了操作系统映像文件的执行,显示出hello,world

持续更新中……
我是桐小白,一个摸爬滚打的计算机小白

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值