自制操作系统-使用汇编显示 hello world
Windows (开机)读软盘第一个扇区的读法的具体表格
Hello World汇编版
就是将16进制编写的代码使用汇编语言编写出来
- ; cherry-os
- ORG 0x7c00 ;指定程序装载的位置
- ;下面用于描述FAT12格式的软盘
- JMP entry
- DB 0x90
- DB "CHRRYIPL" ;启动区的名称可以是任意的字符串,但长度必须是8字节
- DW ; 每一个扇区的大小,必须是512字节
- DB ;簇的大小(必须为1个扇区)
- DW ;FAT的起始位置(一般从第一个扇区开始)
- DB ;FAT的个数 必须是2
- DW ;根目录的大小 一般是224项
- DW ; 该磁盘的大小 必须是2880扇区
- DB 0xf0;磁盘的种类 必须是0xf0
- DW ;FAT的长度 必须是9扇区
- DW ;1个磁道(track) 有几个扇区 必须是18
- DW ; 磁头个数 必须是2
- DD ; 不使用分区,必须是0
- DD ; 重写一次磁盘大小
- DB ,,0x29 ;扩展引导标记 固定0x29
- DD 0xffffffff ;卷列序号
- DB "CHERRY-OS " ;磁盘的名称(11个字节)
- DB "FAT12 " ;磁盘的格式名称(8字节)
- TIMES DB ; 先空出18字节 这里与原文写法不同
- ;程序核心
- entry:
- MOV AX, ;初始化寄存器
- MOV SS,AX
- MOV SP,0x7c00
- MOV DS,AX
- MOV ES,AX
- MOV SI,msg
- putloop:
- MOV AL,[SI]
- ADD SI,
- CMP AL,
- JE fin
- MOV AH,0x0e ;显示一个文字
- MOV BX, ;指定字符的颜色
- INT 0x10 ;调用显卡BIOS
- JMP putloop
- fin:
- HLT ;CPU停止,等待指令
- JMP fin ;无限循环
- msg:
- DB 0x0a , 0x0a ;换行两次
- DB "hello, cherryOS"
- DB 0x0a
- DB
- TIMES 0x1fe-($-$$) DB ;填写0x00,直到0x001fe
- DB 0x55, 0xaa
将这个文件保存为cherryOS.asm,使用nasm生成cherryOS.img
- nasm cherryOS.asm -o cherryOS.img
使用QEMU运行我们的系统
- qemu-system-i386 cherryOS.img
效果图:
代码说明
书中使用的是NASK,我们使用的是NASM,部分语法不同,这里总结一下。
1
2
3
4
5
|
NASK代码 NASM代码
JMP entry -> JMP SHORT entry
RESB <填充字节数> -> TIMES <填充字节数> DB <填充数据>
RESB 0x7dfe-$ -> TIMES 0x1fe-($-$$) DB 0
ALIGNB 16 -> ALIGN 16, DB 0
|
下面对一个语句做专门说明
1
|
TIMES 0x1fe-($-$$) DB 0
|
这一句其中出现了$与$$这样的符号。
$ 是当前位置
$$ 是段开始位置
$ - $$ 是当前位置在段内的偏移
比如我们前面输入了130个字节,那么$ - $$就是130,使用0x1fe-($ - $$)就可以计算出到达0x1fe还需要多少个字节。
这样就保证了我们循环填充后所停在的位置是0x1fe
上面的代码中出现了FAT12格式,IPL这样的词语。这里简要说明。
FAT12: Windows MS-DOS所采用的软盘格式。后面我们将使用FAT32作为我们系统的格式。
启动区: 软盘的第一个扇区成为启动区。
扇区: 计算机读写软盘的过程中不是一个字节一个字节的读写,而是以512字节为一个单位进行读写的。因此,软盘的512个字节就是一个扇区。扇区就是最小的读写单元。
IPL:initial program loader的缩写。启动程序加载器,启动区只有区区512字节,实在是太小了。所以我们需要一个专门的程序IPL去启动操作系统
bootsrap:鞋带。操作系统的启动就是操作系统的一个自救过程,我们一般将操作系统的启动机制叫做bootstrap。
几个语句:
ORG:这个指令将告诉编译器,在代码开始执行的时候,这些代码将被装载到哪个地址中,比如我们在这里指定的地址是0x7c00。(为什么是0x7c00,IBM的大佬们当年规定的就是这个数字,我也没办法)
JMP:JMP,跳转,转到对应的语句。
MOV:这个不多说了,相当于赋值语句。MOV AX,0 就是将0赋值给AX
HLT:让CPU停止动作的指令,并不是完全的停止,只是让CPU进入等待状态。
INT:BIOS中断指令,这里我们用到INT0x10调用显卡,更多的有关BIOS的中断可以自行百度。
四个代码块:
entry:程序的开始,主要用来初始化寄存器和将msg的地址放入SI
putloop:用于显示一个字符,整个流程就是这个代码段所表示的过程,AH默认0x0e,AL表示字符,BH默认为0,BL表示颜色。具体参考INT0x10中断内容。
fin:让CPU进行等待。这个代码段要在代码中看,我们是这么写的CMP AL,0 JE fin。JE表示 jump if equal。所以这句话的意思是,如果AL==0 那么跳转到fin。也就是说我们msg中的信息显示完成后,就让CPU进入无限等待状态。
msg:用于显示我们的内容
几个寄存器:
虽然这都是基础了,但是还是写一下,省的大家百度了
AX 累加寄存器 BX 基址寄存器 CX计数寄存器 DX数据寄存器
SP 栈指针寄存器 BP 基址指针寄存器 SI 源变址寄存器 DI 目的变址寄存器
ES 附加段寄存器 CS 代码段寄存器 SS 堆栈段寄存器 DS 数据段寄存器
L与H:H表示高位,L表示地位,AL表示AX寄存器低位,AH表示AX寄存器的高位
整体流程:
- 首先进入entry,entry中完成了对寄存器的初始化,并且将msg的地址放到SI中,此时可以将SI理解成一个在msg数据中滑动的指针。
- msg内部是我们需要显示的字符串
- 进入putloop,这个循环用于将msg的字符一个一个打印出来。如果AH = 0时,进入fin。
- 进入fin,程序变为无限等待状态。
参考:
http://blackblog.tech/2018/07/18/CreateOSDay2/
自制操作系统-使用汇编显示 hello world的更多相关文章
- 自制操作系统Antz(13) 显示图片
显示图片只是在多媒体课上看着bmp格式图片的突发奇想,然后就实现在了我自己的操作系统 Antz系统更新地址 Linux内核源码分析地址 Github项目地址 效果图: 显示图片的原理 在之前显卡操作时 ...
- 30天自制操作系统(三)进入32位模式并导入C语言
1 制作真正的IPL IPL(Initial Program Loader),启动程序装载器,但是之前并没有实质性的装载任何程序,这次作者要开始装载程序了. 虽然现在开发的操作系统啥功能也没有,作者说 ...
- 《30天自制操作系统》笔记3 --- (Day2 上节)完全解析文件系统
Day2 汇编语言学习与Makefile入门 本文仅带着思路,研究源码里关于文件系统的参数 关于day2主程序部分及更多内容,请看<30天自制操作系统>笔记 导航 发现学习中的变化 源码差 ...
- 《30天自制操作系统》笔记(06)——CPU的32位模式
<30天自制操作系统>笔记(06)——CPU的32位模式 进度回顾 上一篇中实现了启用鼠标.键盘的功能.屏幕上会显示出用户按键.点击鼠标的情况.这是通过设置硬件的中断函数实现的,可以说硬件 ...
- 《30天自制操作系统》笔记(03)——使用Vmware
<30天自制操作系统>笔记(03)——使用Vmware 进度回顾 在上一篇,实现了用IPL加载OS程序到内存,然后JMP到OS程序这一功能:并且总结出下一步的OS开发结构.但是遇到了真机测 ...
- 《30天自制操作系统》笔记(02)——导入C语言
<30天自制操作系统>笔记(02)——导入C语言 进度回顾 在上一篇,记录了计算机开机时加载IPL程序(initial program loader,一个nas汇编程序)的情况,包括IPL ...
- 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!
<30天自制操作系统>笔记(01)——hello bitzhuwei's OS! 最初的OS代码 ; hello-os ; TAB=4 ORG 0x7c00 ; 指明程序的装载地址 ; 以 ...
- 从你的u盘启动:30天自制操作系统第四天u盘启动学习笔记
暑假学习小日本的那本书:30天自制操作系统 qq交流群:122358078 ,更多学习中的问题.资料,群里分享 developing environment:ubuntu 关于u盘启动自己做的操 ...
- 30天自制操作系统第八天学习笔记(u盘软盘双启动版本)
暑假学习小日本的那本书:30天自制操作系统 qq交流群:122358078 ,更多学习中的问题.资料,群里分享 environment:开发环境:ubuntu 第八天的学习思考: 关于鼠标是怎么 ...
随机推荐
- codefroce 854 A.Fraction
题解:贪心,每次从能够出发的飞机中取一个最大的就好啦,用一个队列维护一下~ ac代码: #include <cstdio> #include <iostream> #inclu ...
- (六)mybatis之多对一关系(简单)
一.需求分析 需求: 查询所有订单信息及订单下的订单明细信息 分析: 一条订单只能由一个消费者下单,但是一条订单有多条订单明细. 二.创建数据库表和实体对象 Customer.java ...
- Android Service的有关总结
来自一位网友的评论 1.使用方式 startService 启动的服务 主要用于启动一个服务执行后台任务,不进行通信.停止服务使用stopService bindService 启动的服务 该方法启动 ...
- vue 2.0+ 怎么写本地接口获取数据
在vue-cli脚手架项目中,找到build ---- webpack.dev.conf.js 文件,具体位置如下图: 找到文件后添加下面的内容,写在头部: //这是 webpack.dev.conf ...
- mysql 创建用户,授权,查询用户等
MySQL创建用户与授权 一. 创建用户 命令: CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明: username:你将创建的用 ...
- ajax _flask
同步访问 当客户端向服务器发送请求时,服务器在处理过程中,浏览器只能等等,效率偏低 异步访问: 当客户端向服务器发送请求时,服务器在处理过程中,客户端可以做其他的操作,不需要一直等待,效率偏高 AJA ...
- 使用SQLAlchemy,以及问题处理
https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0014021031294178 ...
- Fiddler之文件代理
开发中,上线的一个页面有bug,但是在本地的环境和测试环境却没有任何问题,只能按照自己的猜测去修复其中的bug,修改了再发布到测试环境,然后再到生产,发现bug定位不对,只能继续猜测,继续发到测试环境 ...
- python3 多线程和多进程
一.线程和进程 1.操作系统中,线程是CPU调度和分派的基本单位,线程依存于程序中 2.操作系统中,进程是系统进行资源分配和调度的一个基本单位,一个程序至少有一个进程 3.一个进程由至少一个线程组成, ...
- java学习笔记13-重写与重载
重写 重写是子类对父类允许访问的方法实现过程进行重新编写,返回值和参数都不能变. 重写方法不能抛出新的检查异常和比被重写方法更加宽泛的异常 访问权限不能比被重写方法低 声明为final的方法不能被重写 ...