自制操作系统(1)从Hello World开始 |
您所在的位置:网站首页 › 自己编写操作系统需要什么软件 › 自制操作系统(1)从Hello World开始 |
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 |