30天自制操作系统第三天暂时代码

2024-05-10 02:36

本文主要是介绍30天自制操作系统第三天暂时代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

; haribote-ipl
; TAB=4ORG		0x7c00			; このプログラムがどこに読み込まれるのか; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述JMP		entryDB		0x90DB		"HARIBOTE"		; ブートセクタの名前を自由に書いてよい(8バイト)DW		512				; 1セクタの大きさ(512にしなければいけない)DB		1				; クラスタの大きさ(1セクタにしなければいけない)DW		1				; FATがどこから始まるか(普通は1セクタ目からにする)DB		2				; FATの個数(2にしなければいけない)DW		224				; ルートディレクトリ領域の大きさ(普通は224エントリにする)DW		2880			; このドライブの大きさ(2880セクタにしなければいけない)DB		0xf0			; メディアのタイプ(0xf0にしなければいけない)DW		9				; FAT領域の長さ(9セクタにしなければいけない)DW		18				; 1トラックにいくつのセクタがあるか(18にしなければいけない)DW		2				; ヘッドの数(2にしなければいけない)DD		0				; パーティションを使ってないのでここは必ず0DD		2880			; このドライブ大きさをもう一度書くDB		0,0,0x29		; よくわからないけどこの値にしておくといいらしいDD		0xffffffff		; たぶんボリュームシリアル番号DB		"HARIBOTEOS "	; ディスクの名前(11バイト)DB		"FAT12   "		; フォーマットの名前(8バイト)RESB	18				; とりあえず18バイトあけておく; プログラム本体entry:MOV		AX,0			; レジスタ初期化MOV		SS,AXMOV		SP,0x7c00MOV		DS,AX; ディスクを読むMOV		AX,0x0820MOV		ES,AXMOV		CH,0			; シリンダ0MOV		DH,0			; ヘッド0MOV		CL,2			; セクタ2MOV		SI,0			; 失敗回数を数えるレジスタ
retry:MOV		AH,0x02			; AH=0x02 : ディスク読み込みMOV		AL,1			; 1セクタMOV		BX,0MOV		DL,0x00			; AドライブINT		0x13			; ディスクBIOS呼び出しJNC		fin				; エラーがおきなければfinへADD		SI,1			; SIに1を足すCMP		SI,5			; SIと5を比較JAE		error			; SI >= 5 だったらerrorへMOV		AH,0x00MOV		DL,0x00			; AドライブINT		0x13			; ドライブのリセットJMP		retry; 読み終わったけどとりあえずやることないので寝るfin:HLT						; 何かあるまでCPUを停止させるJMP		fin				; 無限ループerror:MOV		SI,msg
putloop:MOV		AL,[SI]ADD		SI,1			; SIに1を足すCMP		AL,0JE		finMOV		AH,0x0e			; 一文字表示ファンクションMOV		BX,15			; カラーコードINT		0x10			; ビデオBIOS呼び出しJMP		putloop
msg:DB		0x0a, 0x0a		; 改行を2つDB		"load error"DB		0x0a			; 改行DB		0RESB	0x7dfe-$		; 0x7dfeまでを0x00で埋める命令DB		0x55, 0xaa

第一部分代码: 

  1. ORG 0x7c00 - 设置程序加载到内存的基地址为0x7c00,这是BIOS将引导扇区加载到内存的标准位置。

  2. JMP entry - 无条件跳转到标签entry,这是程序主体的开始位置。

  3. DB 0x90 - 插入一个单字节(0x90),用于指令对齐。

  4. DB "HARIBOTE" - 引导扇区的标识名,最长为8个字符。这里命名为"HARIBOTE"。

  5. DW 512 - 定义每个磁盘扇区的大小为512字节。这是FAT12和大多数磁盘格式的标准扇区大小。

  6. DB 1 - 定义每个簇包含的扇区数量为1,对于FAT12格式来说,这是一个常见的设置。

  7. DW 1 - 定义文件分配表(FAT)的起始扇区为第1扇区。

  8. DB 2 - 指定FAT的副本数为2,这是为了在文件系统损坏时提供冗余保护。

  9. DW 224 - 定义根目录区可以存储的最大文件/目录条目数为224。这是FAT12文件系统的一个典型设置。

  10. DW 2880 - 定义磁盘的总扇区数为2880。这通常对应于一个标准的1.44MB 3.5英寸软盘。

  11. DB 0xf0 - 定义磁盘的媒体类型代码为0xf0,这是一个用于固定磁盘和某些类型软盘的标准代码。

  12. DW 9 - 指定每个FAT的扇区数为9,这是管理文件和目录所需的空间大小。

  13. DW 18 - 定义每个磁道的扇区数为18,这是标准的软盘几何配置。

  14. DW 2 - 定义磁头数为2,这是双面软盘的典型配置。

  15. DD 0 - 因为这是一个无分区的启动磁盘,所以这里设置为0。

  16. DD 2880 - 再次声明磁盘的总扇区数为2880,确保磁盘描述的一致性。

  17. DB 0,0,0x29 - 这是一组固定的值,通常用于标识引导扇区。0x29是一个用于引导扇区的魔术数字。

  18. DD 0xffffffff - 预置的卷序列号,通常用于磁盘识别。

  19. DB "HARIBOTEOS " - 磁盘卷标,最长11个字符。这里命名为"HARIBOTEOS"。

  20. DB "FAT12 " - 文件系统类型名,最长8个字符。这里使用"FAT12"。

  21. RESB 18 - 保留18字节的空白,这些空间可能用于未来扩展或保持扇区对齐。

 整体来看,这段代码为一个FAT12格式的软盘设置了必要的引导参数和磁盘布局信息,使得计算机的BIOS能够正确地读取并执行引导程序。

 第二部分代码:

程序入口和初始化部分

  • entry: 标签指示程序的开始点。
  • MOV AX, 0 初始化寄存器AX为0。
  • MOV SS, AX 将堆栈段寄存器(SS)设置为0,表示堆栈段的开始。
  • MOV SP, 0x7c00 设置堆栈指针(SP)为0x7c00,指向程序被加载到的内存位置。
  • MOV DS, AX 将数据段寄存器(DS)设置为0,初始化数据段。

 

  • retry: 这是一个标签,用作重试读取操作的起点。

  • MOV AH, 0x02 设置AH寄存器的值为0x02,这是BIOS中断服务用于读取磁盘的功能码。

  • MOV AL, 1 设置AL寄存器的值为1,指示需要从磁盘读取1个扇区。

  • MOV BX, 0 设置BX寄存器为0,通常BX被用作缓冲区在内存中的偏移地址,这里设置为0可能是将数据直接读入某个预定的基地址(如ES:BX)。

  • MOV DL, 0x00 设置DL寄存器的值为0x00,这指定了要读取数据的驱动器编号,0x00通常表示软盘的A驱动器。

  • INT 0x13 调用中断0x13,这是BIOS提供的磁盘服务中断,用来根据AH和其他寄存器的设置执行具体的磁盘操作(这里是读取操作)。

  • JNC fin 判断上一条指令的执行结果,JNC(Jump if Not Carry)指令用于检查进位标志(Carry Flag),如果未设置(即没有错误),则跳转到fin标签,完成操作。

  • ADD SI, 1 如果读取失败(即进位标志被设置),则将SI寄存器的值加1。SI寄存器在这里被用作失败次数的计数器。

  • CMP SI, 5 将SI寄存器的值与5进行比较,检查是否已经达到最大重试次数。

  • JAE error 如果SI的值大于或等于5(JAE是Jump if Above or Equal),则跳转到error标签,处理错误情况。

  • MOV AH, 0x00 设置AH寄存器为0x00,准备调用磁盘重置功能。

  • MOV DL, 0x00 再次确认DL寄存器的值为0x00,指定A驱动器。

  • INT 0x13 再次调用中断0x13,这次是为了重置磁盘驱动器,尝试清除任何错误状态。

  • JMP retry 最后,无论重置是否成功,都会无条件跳回retry标签,重新尝试读取操作,除非已经达到最大重试次数并跳转到错误处理。

  • fin: - 这是一个标签,代码的执行流在此处继续。通常,这个标签在代码中被其他部分(如读取磁盘成功后)引用跳转到。

  • HLT - 这条指令使CPU进入暂停状态,停止执行指令并减少功耗,直到下一个外部中断到来。HLT(Halt)指令常用于操作系统的空闲循环和引导程序的末尾,以避免无用的处理器活动。

  • JMP fin - 这是一个无条件跳转指令,它跳转到自己(即fin标签本身)。这创建了一个无限循环,确保即使在收到中断唤醒处理器后,处理器仍然不会执行其他未定义的代码区域。此循环确保程序保持在已知的状态。

 

  • error: - 这是一个标签,用作错误处理部分的开始点。通常在程序的其他部分检测到错误时会跳转到这个位置。

  • MOV SI, msg - 这条指令将msg标签处的内存地址移动到寄存器SI中。在汇编语言中,SI通常用于索引和指针操作,这里用作指向错误信息字符串的指针。msg很可能是定义在程序中某处的字符串(如错误消息),这个指令的目的是为了准备在后续代码中遍历并显示这条消息。

 

这段代码是一个用于显示错误信息的循环,详细说明如下:

  • putloop: - 这是一个标签,定义了循环的开始。这段代码用于输出msg标签指向的字符串中的字符。

  • MOV AL, [SI] - 从内存地址指向的位置(由SI寄存器指定)加载一个字节到AL寄存器。AL寄存器通常用于存储单个字符,这里它被用来存储错误消息中的当前字符。

  • ADD SI, 1 - 将SI寄存器的值加1,移动到错误消息的下一个字符。这是字符串遍历的常见方式,SI在这里作为指针逐字节移动通过字符串。

  • CMP AL, 0 - 将AL寄存器中的值与0比较,以检查是否到达字符串的结尾(C语言风格的以null(0)结尾的字符串)。

  • JE fin - 如果上一条比较指令发现AL中的值是0(即到达了字符串的结尾),则跳转到fin标签,结束循环和程序。

  • MOV AH, 0x0e - 设置AH寄存器为0x0e,这是视频BIOS的功能号,用于在屏幕上显示单个字符。这里准备调用BIOS中断来显示一个字符。

  • MOV BX, 15 - 设置BX寄存器为15,这通常表示文本模式下的颜色属性(例如白色前景和黑色背景)。BIOS中断0x10将使用这个属性来显示字符。

  • INT 0x10 - 调用中断0x10,这是一个多功能视频BIOS中断,AH=0x0e告诉BIOS在文本模式下显示AL中的字符。

  • JMP putloop - 无条件跳转回putloop标签,继续循环过程,直到遍历完成整个字符串。

这个循环确保错误消息可以被完整地显示在屏幕上,每次循环显示一个字符,直到字符串结束。这是系统低级错误处理中常见的反馈方式,用户可以看到错误信息,了解系统运行中遇到的问题。

 

 

这部分代码位于一个引导扇区的结尾部分,包含用于显示错误消息以及引导扇区正确结束的标记。下面是对这段代码的详细解释:

  • msg: - 这是一个标签,用作错误信息字符串的开始点。

  • DB 0x0a, 0x0a - 定义两个字节的数据,每个字节是0x0a,代表ASCII中的换行符(Line Feed,LF)。这里用两个连续的换行符开始错误消息,意在屏幕上提供视觉上的间隔。

  • DB "load error" - 定义一个字符串"load error",这是实际的错误消息文本。

  • DB 0x0a - 再次定义一个字节的数据,是一个换行符,用于错误消息后提供一个新的行开始。

  • DB 0 - 定义一个字节的数据,其值为0。这是一个字符串终止符,用于标记字符串的结束,符合C语言风格的字符串定义。

  • RESB 0x7dfe-$ - 这是一个保留字节的指令,RESB用于保留指定数量的字节。0x7dfe-$计算从当前位置到内存地址0x7dfe的字节数,这条指令确保填充这段空间,使得引导扇区的总大小达到0x7dfe字节。

  • DB 0x55, 0xaa - 最后定义两个字节的数据,0x550xaa。这两个字节是引导扇区的签名,用于BIOS检测这个扇区是否是有效的引导扇区。只有包含这个签名的扇区才能被BIOS认为是可启动的,这是PC兼容机引导过程的一部分标准。

整体来看,这段代码不仅提供了错误信息的输出内容,同时确保了引导扇区的结构完整性和启动合法性,通过填充和引导签名的设定使得整个引导扇区满足BIOS的引导要求。

这篇关于30天自制操作系统第三天暂时代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/975192

相关文章

【Linux进阶】UNIX体系结构分解——操作系统,内核,shell

1.什么是操作系统? 从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核(kerel),因为它相对较小,而且位于环境的核心。  从广义上说,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并使计算机具有自己的特生。这里所说的其他软件包括系统实用程序(system utility)、应用程序、shell以及公用函数库等

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

公共筛选组件(二次封装antd)支持代码提示

如果项目是基于antd组件库为基础搭建,可使用此公共筛选组件 使用到的库 npm i antdnpm i lodash-esnpm i @types/lodash-es -D /components/CommonSearch index.tsx import React from 'react';import { Button, Card, Form } from 'antd'

17.用300行代码手写初体验Spring V1.0版本

1.1.课程目标 1、了解看源码最有效的方式,先猜测后验证,不要一开始就去调试代码。 2、浓缩就是精华,用 300行最简洁的代码 提炼Spring的基本设计思想。 3、掌握Spring框架的基本脉络。 1.2.内容定位 1、 具有1年以上的SpringMVC使用经验。 2、 希望深入了解Spring源码的人群,对 Spring有一个整体的宏观感受。 3、 全程手写实现SpringM

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

代码随想录算法训练营:12/60

非科班学习算法day12 | LeetCode150:逆波兰表达式 ,Leetcode239: 滑动窗口最大值  目录 介绍 一、基础概念补充: 1.c++字符串转为数字 1. std::stoi, std::stol, std::stoll, std::stoul, std::stoull(最常用) 2. std::stringstream 3. std::atoi, std

记录AS混淆代码模板

开启混淆得先在build.gradle文件中把 minifyEnabled false改成true,以及shrinkResources true//去除无用的resource文件 这些是写在proguard-rules.pro文件内的 指定代码的压缩级别 -optimizationpasses 5 包明不混合大小写 -dontusemixedcaseclassnames 不去忽略非公共

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用。如果你看不懂,请留言。 完整代码: <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><ti

操作系统实训复习笔记(1)

目录 Linux vi/vim编辑器(简单) (1)vi/vim基本用法。 (2)vi/vim基础操作。 进程基础操作(简单) (1)fork()函数。 写文件系统函数(中等) ​编辑 (1)C语言读取文件。 (2)C语言写入文件。 1、write()函数。  读文件系统函数(简单) (1)read()函数。 作者本人的操作系统实训复习笔记 Linux

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa