自制操作系统(1)从Hello World开始

您所在的位置:网站首页 自己编写操作系统需要什么软件 自制操作系统(1)从Hello World开始

自制操作系统(1)从Hello World开始

2024-05-24 09:06| 来源: 网络整理| 查看: 265

Copyright (C) XP用户123 zhouzhihao 2021.3.13

大家期待已久的自制操作系统来了!!!

从今天开始,每周天更新一篇自制操作系统哦。

1.1、前言&准备工作

恭喜点进来的朋友们,解锁在B站学制作操作系统成就!!!

说老实话,我自己都还不太了解操作系统,因为它的种类太多了!像Windows、Liunx、Ubuntu,或者是古老的MS-DOS、PC-DOS,甚至是别人自制的OSASK、Haribote OS等,我来都来不及去了解它们,因为我的计算机配置不允许(笑)。不过,只要能让计算机启动,且在运行状态的东西,都可以叫“操作”系统。所以这么说,我们只做一个在计算机上显示字符的东西,也可以叫操作系统了!再三思想,就显示“Hello World”吧(笑)!

哦,对了!操作系统是底层的东西,所以我们只能使用汇编语言来开发,像C语言、Pasic语言、Java语言,还是等以后再说吧。

顺便一提,计算机接通电源时,会将控制权交给BIOS(Basic Input Output System),待BIOS完成自检和其他杂七杂八的工程后,将控制权交给一个可启动的设备,而这个设备里就需要装有操作系统,我们做操作系统就是为了使计算机成功启动并可以使用。

这时候有人会说了:“你啰啰嗦嗦一大堆,还不讲制作系统!”呃,现在还得走一下准备工作才可以开始。

首先新建一个文件夹在D盘根目录(我喜欢这样),将文件夹名称改为自己要制作的操作系统的名称,这里就以“Powerint DOS”为例。下载一个tools工具包(开发工具),

链接:https://pan.baidu.com/s/1UEh-Q5dULgtbeyIms42odQ  提取码:zhou

将其放入“Powerint DOS”文件夹,然后再在“Powerint DOS”文件夹里新建一个“kernel”文件夹(内核)。以后,在“Powerint DOS”文件夹中,tools为工具文件夹,kernel为内核文件夹。

说到开发,就需要一个写代码能标关键字的工具,这里推荐Notepad++哦!

链接:https://dl.pconline.com.cn/html_2/1/117/id=10699&pn=0.html

1.2、使用2进制编辑器制作

准备工作做好了,可以开始动手开发了!要是再不开发,我就要被人说闲话贼多了(笑)。这次,我们不需要C语言编译器,不需要汇编语言工具包。只需要下载2进制编辑器BZ,链接:https://www.veryhuo.com/down/html/62222.html

下载完成后打开BZ,新建一个2进制文件(boot.bin),按照下图依次输入进文件就行了。

注意1F0那边有东西哦!

这么多的00,估计要打到猴年马月去呢(笑)。输入完后点击保存到boot.bin,用VMware打开运行后出现了Hello World!!!

运行后boot.bin后的样子

不知道读者们有没有激动的心情呢?

1.3、使用汇编语言制作(一)

上面一节的麻烦操作,连汇编语言挨都没挨边呢!不过是让大家尝尝甜头而已,现在我们就得打起十二分的精神了(笑),但这并不代表2进制编辑器没有用哦!

在“kernel”文件夹中新建一个叫做“boot.asm”的文件,可能会有读者会问:“.asm文件是啥???”.asm文件就是写汇编语言代码的文件,“boot.asm”就是引导扇区的源代码。好,不多说不多说,上代码!

此处的boot.asm:

1.jmp start

2.string db 'Hello World','$'

3.start:

4.mov ax,7c0h

5.mov ds,ax

6.mov es,ax

7.mov si,string

8.call putstr

9.jmp $

10.putstr:

11.mov al,[si]

12.cmp al,'$'

13.je .ret

14.mov ah,0eh

15.int 10h

16.inc si

17.jmp putstr

18..ret:

19.ret

20.times 510-($-$$) db 0

21.db 0x55,0xaa

我相信肯定会有几位读者很懵,不过这才是冰山一角,大家要有学下去的动力哦!

这段代码全是新指令,我们就从上往下看看吧。

首先是jmp指令。jmp源于英语里的jump,翻译过来为“跳转”的意思,类似于C语言里的goto。现在就好理解了,它的意思就是“跳转至start处”,简单吧!

然后是db指令,db源于英语的“define byte”,定义字节数据(一字节就是一个英文字符哦)。

重点讲mov指令,mov源于move,意思“移动”。用法非常简单,就是赋值。但却是汇编语言的重点,“mov si,0”意思就是“si=0”,跟copy一个德行。这是有人会问:“si是个什么东西?”

那就来讲讲si,si是一个寄存器,和它一样的通用寄存器有8个:

ax,bx,cx,dx,si,di,sp,bp

这些都是16位寄存器,可以容纳2个字节。不过,前四个可以拆分成两个8位寄存器 ,后四个不行。高八位叫什么h,低八位叫什么l,比如ax高八位叫ah,低八位叫al。接下来再看看它们的常用功能吧!

AX――累加器(Accumulator),使用幅度最高

BX――基址寄存器(Base Register),常存放数据地址

CX――计数器(Count Register),常作为计数器

DX――数据寄存器(Data Register),存放数据

SI――源变址寄存器(Source Index),常存放数据地址

DI――目的变址寄存器(Destination Index),常存放数据地址

SP――堆栈指针寄存器(Stack Pointer),指向堆栈的栈顶地址

BP――基址指针寄存器(Base Pointer),指向内存的基地址

除了通用寄存器,还有段寄存器,总共4个:

cs,ds,es,ss

这几个寄存器虽然都是16位的,但是作用却比通用寄存器高了好几个档次。cs是代码段寄存器(code segment),它的作用可大了,我们的代码位置都是由它来决定的,比如说:位置100有一串代码,那么cs就要等于100,才能执行此位置的代码。ds是数据段寄存器(data segment),它的作用也很大,你必须定义它才能获取数据。es和ds作用相同(extra segment),只不过不一定需要定义。ss是堆栈段寄存器(stack segment),一个很重要的寄存器,也是执行堆栈操作的基本。所以,这就是为啥一开始就要给ds和es赋值,因为不给他两赋值,就得不到Hello World的位置了。

继续讲指令。call和ret是搭配使用的,call的意思是调用,ret是return的缩写,和C语言里的是一样的作用。

cmp是比较指令,“cmp al,1”就是比较al和1。

je是“jump if equal”的缩写,相同则跳转的意思,常和cmp搭配使用。

int是也一个重点,这个int会使大家想起C语言里的整数定义。不过它在汇编语言里可不是这样,意思为“中断调用”,呃,现在给大家讲中断调用还不是太合适,这个要得过一会。因为它涉及到了硬件之类的东西。总之,它的意思就是BIOS给我们设置的函数,供我们调用的。跟call差不多。ah=0eh int 10h就是打印一个字符的函数,入口:al=字符。

inc不多讲,就是往里加一的意思。

读到这里,我相信大家都知道代码的意思了。不过为了以防万一,还是把这段代码翻译成C语言吧(笑)!

翻译过后的boot.asm:

1.goto start

2.*string="Hello World$"

3.start:

4.ax=0x7c00

5.ds=ax

6.es=ax

7.si=&string

8.putstr(si)

9.goto $

10.putstr:

11.al=si[i]

12.if (al=="$")

13.goto .ret

14.ah=0x0e

15.(无法翻译)

16.i++

17.goto putstr

18..ret:

19.return

20.(无法翻译)

21.(无法翻译)

是不是好懂多了呢?

好,讲完了代码,还得讲一讲怎么编译代码。我们使用的汇编语言工具包叫做“nasm”,一个举世闻名的汇编语言编译器。将boot.asm放入和nasm.exe同一个文件夹里,打开cmd,输入nasm boot.asm -o boot.bin 就行了,然后再用VMware运行。喔拉,Hello World就出来啦!!!

用汇编语言写也成功了!

汇编语言写Hello World有个好处,就是可以更改代码和字符,你可以显示别的东西什么之类的。总之,我们以后会经常见到汇编语言的!

1.4、使用汇编语言制作(二)

呃,不知道读者们是不是厌烦了干燥的代码解析,不过,现在我们要利用现有的技术加上“一”点点而外知识,来做一个蓝底白字的Hello World,怎么样啊(笑)?

此处的boot.asm:

1.jmp start

2.string db 'Hello World','$'

3.start:

4.mov ax,7c0h

5.mov ds,ax

6.mov es,ax

7.mov bh,1fh

8.mov cx,0000

9.mov dx,0011

10.call paint

11.mov si,string

12.call putstr

13.jmp $

14.putstr:

15.mov al,[si]

16.cmp al,'$'

17.je .ret

18.mov ah,0eh

19.int 10h

20.inc si

21.jmp putstr

22..ret:

23.ret

24.paint:

25.mov ah,06h

26.mov al,0

27.int 10h

28.ret

29.times 510-($-$$) db 0

30.db 0x55,0xaa

是不是都是眼熟的代码呀(笑)?这次的新代码不多哟,先运行看一下!

非常的悦目啊!

不知道有没有读者看到,代码的数字部分有的末尾加了h,有的没有呢?

h是hex的缩写,意思是16进制。听起来可能很陌生,不过我可以告诉你,我们现在通用的是10进制数字。

在16进制里,超过9的部分都成了ABCDEF,且末尾要加h,比如说:1Ah就是26、36就是24h。代码里还出现了新的int,就是ah=06h int 10h,作用就是画颜色。入口:cx=左上角行、列,dx=右下角行、列,al=显示页,bh=颜色。

说到16进制颜色,我就给大家列张表:

0=黑色 1=蓝色 2=绿色 3=青色

4=红色 5=粉色 6=黄色 7=灰色

8=深灰 9=亮蓝 A=亮绿 B=亮青

C=亮红 D=亮粉 E=亮黄 F=白色

综上所述,1F就是背景为蓝、字体为白的颜色。

如果你觉得不过瘾、可以换一个醒目的颜色并填满屏幕呢(笑)!

1.5、使用汇编语言制作(三)

这回,我们来做更有趣的事情,让Hello World居中。是不是很有趣呀(笑)?

提前说一声,要想让Hello World居中,得算出中间的行和列:

行=总行数(24)÷2=12

列=总列数(79)÷2=34.5

另外,设定光标位置是ah=02h int 10h,入口:bh=显示页,dx=行、列。

此处的boot.asm:

1.jmp start

2.string db 'Hello World','$'

3.start:

4.mov ax,7c0h

5.mov ds,ax

6.mov es,ax

7.call setcur

8.mov si,string

9.call putstr

10.jmp $

11.putstr:

12.mov al,[si]

13.cmp al,'$'

14.je .ret

15.mov ah,0eh

16.int 10h

17.inc si

18.jmp putstr

19..ret:

20.ret

21.setcur:

22.mov ah,02h

23.mov bh,0

24.mov dh,12

25.mov dl,34

26.int 10h

27.ret

28.times 510-($-$$) db 0

29.db 0x55,0xaa

不管三七二十一,先运行看看?

真的居中了!

哈,Hello World被我们玩出了这么多的花样!读者们可以将他们融合在一起,说不定会很耀眼呢(笑)!

1.6、INT 10H常用功能

怕读者们看不懂上面的int 10h的功能,这里写一下它的常用功能。

ah=02h,设置光标位置。

入口:bh=显示页,dx=行、列

ah=03h,读取光标位置。

入口:bh=显示页

出口:cx=开始、结束行,dx=行、列

ah=05h,设置显示页。

入口:al=显示页

ah=06h,初始化屏幕。

入口:al=显示页,bh=颜色,cx=左上角行、列,dx=右下角行、列

ah =0eh,显示字符。

入口:al=字符

奥,没想到也讲了这么多啊!这一章就到这结束吧,下一章再见!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3